Programmation Web. Coté serveur : HTML, CSS, PHP, PDO

Dimension: px
Commencer à balayer dès la page:

Download "Programmation Web. Coté serveur : HTML, CSS, PHP, PDO"

Transcription

1 Programmation Web Coté serveur : HTML, CSS, PHP, PDO Rémy Malgouyres LIMOS UMR 6158, IUT, département info Université Clermont 1 B.P AUBIERE cedex http ://

2 Table des matières Table des matières 1 I Documents Hypertexte HTML/CSS 4 1 Pages web statiques HTML HTML, la norme et son évolution Validation W3C et tests de portabilité Structure d un document HTML ou XHTML Premier document HTML Structure du texte en HTML Mise en forme du texte HTML : styles CSS Formes d inclusion de styles CSS Liens Tableaux Insertion d images Figures et sous-figures avec légende Caractères spéciaux Styles CSS et mise en page Éléments HTML de type block et inline Distinguer des parties dans un document : balise div Imbrication des balises et CSS Arborescence de balises et CSS Classes CSS Sélecteurs de style CSS par ID Marges et bordures Positionnement absolu Positionnement relatif Structuration d une page en HTML Exemples de mise en page CSS adaptatifs : Media Queries II Bases du langage PHP 67 3 PHP procédural 71 1

3 TABLE DES MATIÈRES 3.1 Notion de CGI Générer du code HTML avec un CGI en PHP Exemple de fonction en PHP Inclure un fichier PHP dans un autre Arithmétique : types int et float Tableaux indexés : avec une clé de type int Tableaux associatifs : avec une clé de type String Passage de paramètre à un script PHP Variables Locales ou Globales, Références Les classes en PHP Exemples de classes PHP Validation en entrée et gestion d une exception Classe Employe héritant de la classe Personne III Formulaires et Filtrage des Données Utilisateur Formulaires HTML/PHP Formulaires HTML Exemple de style CSS pour formulaire Validation pour la sécurité : Appel de filter_var Appel des vues Tableaux $_POST $_GET $_REQUEST Formulaires dynamiques an javascript Injection, Filtrage, Expressions Régulières Injections HTML et échappement Injections SQL La fonction filter_var Expressions régulières Formulaires PHP/HTML, filtrage, exceptions La Classe Adresse Filtrage des attributs Fabrique d Adresse Génération de formulaires et classe AdresseFormView Enchaînement de la saisie à la vue Les Vues Modification d une Adresse IV Persistance Cookies Création d un cookie Récupération d un cookie Suppression d un cookie

4 TABLE DES MATIÈRES 8.4 Mise à jour d un cookie Sessions Concept de Session et Problèmes de Sécurité Créer une session Création d une session commune à tous les utilisateurs Durée et SID d une session Destruction d une Session Exemple de Session avec SID aléatoire transmis par GET Exemple de Session avec SID aléatoire transmis par COOKIE Exemple Politique de Sécurité en Matière de Session Bases de Données et PHP Data Objects Créer un Base de Données dans phpmyadmin Initiation à PDO : connexion, query, destruction Requêtes Préparées Classe Singleton de Connexion à une Base de Données V Conception d Architectures Avancées Analyse Fonctionnelle Storyboards Diagrammes de Cas d Utilisations Organisation des Répertoires et Configuration Organisation des Répertoires Autoload La classe Config : éviter les URL en dûr Architectures MVC et DAL Le Contrôleur Le Modèle Les Vues La Gateway pour les instances d Adresse Utilisateurs et Front Controller Storyboards Diagramme de Cas d Utilisation Le Front-Controller Gestion de l Authentification

5 Première partie Documents Hypertexte HTML/CSS 4

6 Table of Contents 1 Pages web statiques HTML HTML, la norme et son évolution Validation W3C et tests de portabilité Validateur W3C Tests de portabilité Structure d un document HTML ou XHTML Premier document HTML Structure du texte en HTML Mise en forme du texte HTML : styles CSS Formes d inclusion de styles CSS Liens Tableaux Insertion d images Figures et sous-figures avec légende Caractères spéciaux Styles CSS et mise en page Éléments HTML de type block et inline Éléments blocks Éléments inline Le flux et la propriété CSS display Distinguer des parties dans un document : balise div Imbrication des balises et CSS Arborescence de balises et CSS Classes CSS Sélecteurs de style CSS par ID Marges et bordures

7 TABLE OF CONTENTS 2.8 Positionnement absolu Positionnement relatif Structuration d une page en HTML Exemples de mise en page CSS adaptatifs : Media Queries

8 Chapitre 1 Pages web statiques HTML5 1.1 HTML, la norme et son évolution Le langage HTML, ou Hyper Text Markup Language, permet de décrire et de mettre en forme des documents variés, depuis du simple texte jusqu à des documents multimédia riches avec la définition d HTML 5. Une page HTML est en général destinée à être publiée sur le World Wide Web, où toutes sortes de gens utilisent toutes sortes de navigateurs qui fonctionnent sous sdifférentes platteformes (Mac OS, ipad, Linux, Androïd, MS Windows, etc. pour citer les plus courants). Pour que celà fonctionne, il a été nécessaire de définir un standard pour le langage HTML. C est le standard du World Wide Web Consortium, ou W3C. A noter le rôle déterminant qu a joué la libération du code source du navigateur Netscape par la société Netscape Communications Corporation pour que la pluralité des acteurs n évitent que les standards du web soient de fait propriétaire. 1.2 Validation W3C et tests de portabilité Validateur W3C Lorsqu on écrit une page web en HTML, pour être sûr que celle-ci soit correctement interprétée et affichée par tous les navigateurs qui supportent correctement la norme, il faut valider cette page pour s assurer qu elle est conforme à la norme. Le processus est similaire à l analyse de la syntaxe d un programme par un compilateur et peut se faire en ligne en uploadant le fichier ou en donnant son URL publique. Certains éditeurs proposent une validation interne ou même à la volée. Les scripts en PHP et autre ne peuvent pas être directement validés car ce sont en fait des programmes. Par contre, leur sortie (ce qu ils affichent) doit être du HTML conforme à la norme. 7

9 Rémy Malgouyres, Programmation Web (a) L upload d un fichier HTML (b) Résultat correct sur le validateur W3C Figure 1.1 : Le processus de validation d un fichier HTML sur le validateur W3C Tests de portabilité Même pour un document validé, les navigateurs n ont pas tous la même implémentation du moteur d analyse et de rendu du document, notamment en ce qui concerne les styles par défaut. Pour cette raison, il est indispensable avant de publier un site web, de le tester sur le plus possible de plate-formes et de navigateurs. Ceci peut être simplifié par des outils comme VirtualBox (mais il en existe d autres...), qui permettent en virtualisant de faire tourner simultanément plusieurs systèmes d exploitation sur un même ordinateur. Par exemple, sur la figure 1.2, on voit un exemples où l affichage de la page est testé simultanément avec Internet Explorer et Safari sous Windows, Firefox, Chrome et Opera sous linux et Chrome sous tablette et smartphone Android. Le système Windows tourne en virtuel dans VirtualBox (disponible dans la logitèque d Ubuntu). et le serveur Web (Apache) est instalé en local sous Ubuntu. Les systèmes Windows et Ubuntu sont connectés par un réseau local virtuel interne au système hôte, en l hoccurence Ubuntu. Notons que les navigateurs sur smartphones sont particulièrement capricieux car ils n ont pas les ressources pour implémenter toutes les variantes, surtout sur du code non validé. 8

10 Chapitre 1 : Pages web statiques HTML5 Figure 1.2 : Le processus de test de portabilité avec VirtualBox. 1.3 Structure d un document HTML ou XHTML Un document HTML ou XHTML doit comporter : 1. Sur la première ligne qui ne soit pas constituée d un commentaire : le doctype qui spécifie le type de document (HTML, XHTML et version). Ceci permet que le navigateur puisse supporter et interpréter plusieurs formats de documents. 2. Une balise de début de description de document <html [+attributs]>. 3. Un en-tête compris dans une balise <head>...</head>. 4. Dans le header, une spécification de l encoding ou charset : ISO , latin1, et maintenant systématiquement utf-8. Ce dernier est d ailleurs le défaut utilisé lorsque l encoding n est pas spécifié. 5. Dans le header, de manière optionnelle, une description du style de document (couleurs, polices, tailles, etc.) au format CSS. 6. Un corps du document dans une balise <body>...</body>. 9

11 Rémy Malgouyres, Programmation Web Par exemple, le document Hello World! en XHTML 1.0 strict se compose comme suit : exemples/chapitrehtml/ex01_helloworldxhtml.html 1 <!DOCTYPE html PUBLIC //W3C//DTD XHTML 1. 0 S t r i c t //EN 2 http ://www. w3. org /TR/xhtml1/DTD/xhtml1 s t r i c t. dtd > 3 <! D é c l a r a t i o n du debut d un document HTML avec l a langue : > 4 <html xml :lang= en lang= en xmlns= http ://www. w3. org /1999/ xhtml > 5 <head> <! début de l en t ê t e HTML > 6 <! D é c l a r a t i o n du type d encodage > 7 <meta http equiv= Content Type content= t e x t /html ; c h a r s e t=utf 8 /> 8 <! T i t r e de l a page dans l a f e n ê t r e ou l o n g l e t du n a v i g a t e u r > 9 <t i t l e>my f i r s t XHTML 1. 0 S t r i c t document</ t i t l e> 10 </head> 11 <body> 12 <p>hello world!</p> 13 </body> 14 </html> Le document Hello World! en HTML5 se compose comme suit : exemples/chapitrehtml/ex02_helloworldhtml5.html 1 <! doctype html> 2 <! D e c l a r a t i o n du debut d un document HTML avec l a langue : > 3 <html lang= f r > 4 <head> 5 <meta charset= UTF 8 /> 6 <! D é c l a r a t i o n du type d encodage > 7 <! T i t r e de l a page dans l a f e n ê t r e ou l o n g l e t du n a v i g a t e u r > 8 <t i t l e>my f i r s t HTML 5 document</ t i t l e> 9 </head> 10 <body> 11 <p> 12 Hello world! 13 </p> 14 </body> 15 </html> Le XHTML 1.0 strict possède une syntaxe plus stricte que ses prédécesseurs, simplifiant le travail des navigateurs et des moteurs de recherche. En particulier, toutes les balises sont en minuscules et il y a obligation de fermer les balises, quitte à mettre une balise auto-fermante comme <br/>. La norme HTML5 réintroduit un certain laxisme au niveau de la syntaxe mais il est préférable pour la lisibilité du code de respecter la syntaxe XHTML 1.0 strict dans une page HTML Premier document HTML5 exemples/chapitrehtml/ex03_corps_balises.html 1 <! doctype html> 2 <! D e c l a r a t i o n du debut d un document HTML > 3 <html lang= f r > 4 <! Voici l en t e t e qui d e c l a r e l e s p r o p r i e t e s g e n e r a l e s de l a page > 5 <head> <! debut de l en t e t e HTML > 10

12 Chapitre 1 : Pages web statiques HTML5 6 <! d e c l a r a t i o n de l encodage pour l e s a c c e n t s... > 7 <meta charset= UTF 8 /> 8 <! T i t r e de l a page ( a u s s i t i t r e de l a f e n ê t r e du n a v i g a t e u r ) > 9 <t i t l e>premières b a l i s e s HTML</ t i t l e> 10 </head> 11 <body> <! début du corps HTML > 12 <h1>mon premier f i c h i e r HTML</h1> 13 <p> <! Nouveau paragraphe ( saut de l i g n e ) > 14 Ceci e s t mon premier f i c h i e r HTML. <br/> <! à l a l i g n e > 15 Le body r e p r é s e n t e l e corps du document, 16 dans l e q u e l on met l e t e x t e à a f f i c h e r. 17 </p> <! Fin de paragraphe > 18 <p> 19 Le header ( b a l i s e head ) d é f i n i t l e s p r o p r i é t é s g l o b a l e s du document, 20 t e l l e s que l encodage, l e t i t r e de l a page et des éléments de s t y l e. 21 </p> 22 </body> <! f i n du corps HTML > 23 </html> <! f i n du code HTML > 1.5 Structure du texte en HTML exemples/chapitrehtml/ex04_structure_document.html 1 <! doctype html> 2 <! D e c l a r a t i o n du debut d un document HTML > 3 <html lang= f r > 4 <! Voici l en t e t e qui d e c l a r e l e s p r o p r i e t e s g e n e r a l e s de l a page > 5 <head> <! debut de l en t e t e HTML > 6 <! d e c l a r a t i o n de l encodage pour l e s a c c e n t s... > 7 <meta charset= UTF 8 /> 8 <! T i t r e de l a page ( a u s s i t i t r e de l a f e n ê t r e du n a v i g a t e u r ) > 9 <t i t l e>s t r u c t u r e d un document HTML</ t i t l e> 10 </head> 11 <body> <! début du corps HTML > 11

13 Rémy Malgouyres, Programmation Web 12 <h1>s t r u c t u r e d un document HTML</h1> 13 <p> 14 HTML e s t un langage de d e s c r i p t i o n de documents non WISIWIG, 15 c e s t à d i r e que l e f i c h i e r source ne ressemble pas vraiment 16 au document t e l que l u t i l i s a t e u r f i n a l l e verra.<br/> 17 WISIWIG : <em>what You See I s What You Get</em>. 18 </p> 19 <p> 20 En HTML, l e s <em>b a l i s e s</em>, qui sont encadrées par des &l t ; et &gt ;, 21 <strong>d é f i n i s s e n t l a s t r u c t u r e du document</strong> en c a r a c t é r i s a n t d i f f é r e n t e s 22 p a r t i e s du document ( t i t r e s, paragraphes, tableaux, élément important, 23 l i s t e à puces, images, o b j e t s de type vidéo f l a s h, multimédia pour <em> HTML5</em>, e t c. 24 </p> 25 <p> 26 Par exemple, l a b a l i s e &l t ; p&gt ; &l t ; / p&gt ; d é l i m i t e un 27 paragraphe. Un couple de b a l i s e s avec du t e x t e antre l e s b a l i s e s s a p p e l l e un 28 <em>élément</em>. 29 </p> 30 </body> <! f i n du corps HTML > 31 </html> <! f i n du code HTML > 1.6 Mise en forme du texte HTML : styles CSS exemples/chapitrehtml/ex05_mise_en_forme_locale.html 1 <! doctype html> 2 <! D e c l a r a t i o n du debut d un document HTML > 3 <html lang= f r > 4 <! Voici l en t e t e qui d e c l a r e l e s p r o p r i e t e s g e n e r a l e s de l a page > 5 <head> <! debut de l en t e t e HTML > 6 <meta charset= UTF 8 /> <! D e c l a r a t i o n du type d encodage > 7 <! T i t r e de l a page ( a u s s i t i t r e de l a f e n ê t r e du n a v i g a t e u r ) > 8 <t i t l e>s t y l e CSS HTML locaux</ t i t l e> 12

14 Chapitre 1 : Pages web statiques HTML5 9 </head> 10 <body style= font family : A r i a l Verdana ; font s i z e : 125% ; width : 800px ; > <! début du corps HTML > 11 <h1>mise en forme CSS l o c a l e</h1> 12 <p style= text a l i g n : j u s t i f y ; > 13 Le s t y l e <em>css</em> des éléments permet l a mise en forme ( p o s i t i o n, t a i l l e, couleur, p o l i c e, bordure,... ) 14 d un élément et de son contenu. 15 </p> 16 <p style= text a l i g n : j u s t i f y ; > 17 Un t e x t e j u s t i f i é e s t un t e x t e dont l e bord d r o i t e s t a l i g n é avec l e bord d r o i t de l a 18 b o î t e englobant l e t e x t e. La p r o p r i é t é <em>css</em> <code>text a l i g n</code > permet de 19 g é r e r l alignement ( j u s t i f i é, d r o i t, gauche, c e n t r é ) du t e x t e dans un élément. 20 </p> 21 <p style= text a l i g n :center > 22 La p r o p r i é t é <code>font weight</code> permet de mettre des <span style= font weight :bold ; >éléments en gras</span> 23 ou <span style= font weight :bolder ; >en t r è s gras</span>. 24 <br/> 25 La p r o p r i é t é <code>font v a r i a n t</code> permet de mettre des <span style= font v a r i a n t :small caps ; >éléments en p e t i t e s c a p i t a l e s</span>. 26 <br/> 27 La p r o p r i é t é <code>font s t y l e</code> permet de mettre des <span style= font s t y l e : i t a l i c ; >éléments en i t a l i q u e s</span> 28 <br/> 29 <strong>ces p r o p r i é t é s ne doivent pas ê t r e confondues avec l e s b a l i s e s &l t ; strong&gt ;, &l t ; em&gt ;, e t c. qui d é f i n i s s e n t 30 l a s t r u c t u r e du document ( éléments importants, à s o u l i g n e r, e t c... )</strong> 31 </p> 13

15 Rémy Malgouyres, Programmation Web 32 </body> <! f i n du corps HTML > 33 </html> <! f i n du code HTML > exemples/chapitrehtml/ex06_mise_en_forme_globale.html 1 <! doctype html> 2 <! D e c l a r a t i o n du debut d un document HTML > 3 <html lang= f r > 4 <! Voici l en t e t e qui d e c l a r e l e s p r o p r i e t e s g e n e r a l e s de l a page > 5 <head> 6 <meta charset= utf 8 /> <! D e c l a r a t i o n du type d encodage > 7 <style> 8 /* D é f i n i t i o n du s t y l e */ 9 body { 10 font family : A r i a l Verdana ; 11 font s i z e : 125% ; 12 width : 800px ; 13 } 14 p { 15 text a l i g n : j u s t i f y ; 16 }/* mise en forme des paragraphes */ 17 /* mise en forme du t i t r e */ 18 h1 { 19 text a l i g n : c e n t e r ; 20 font s i z e : 150% ; 21 } 14

16 Chapitre 1 : Pages web statiques HTML5 22 /* mise en forme élémentt important l e s 120% sont r e l a t i f au contexte */ 23 strong { 24 font v a r i a n t : small caps ; 25 font s i z e : 120% ; 26 } 27 </ style> 28 <t i t l e>s t y l e s CSS globaux</ t i t l e> 29 </head> 30 <body> <! début du corps HTML > 31 <h1>mise en forme CSS g l o b a l e</h1> 32 <p> 33 I l peut ê t r e f a s t i d i e u x de g é r e r à chaque b a l i s e l a s pect du t e x t e ou l e graphisme. 34 De plus, une d é f i n i t i o n g l o b a l e du s t y l e de l a page e s t plus modulaire ( un s e u l e n d r o i t 35 à m o d i f i e r pour changer tous l e s s t y l e s des b a l i s e s d un même type. 36 Pour c e t t e raison, <strong>on peut d é f i n i r l e s t y l e <em>css</em> globalement</strong> via une b a l i s e &l t ; s t y l e&gt ; 37 au niveau de l en t ê t e (& l t ; head&gt ; ). 38 </p> 39 <p> 40 Si l on s o u h a i t e changer l a s pect des éléments s t r u c t u r e l s, par exemple 41 dont l importance e s t s o u l i g n é e avec 42 &l t ; strong&gt ; &l t ; / strong&gt ;, 43 on l e d é f i n i t au niveau du s t y l e g l o b a l. 44 </p> 45 <p> 46 On peut a i n s i d é f i n i r l e s s t y l e s typographiques ( fonte,... ) et l a mise 47 en page ( alignement à gauche, à d r o i t e, j u s t i f i é, e t c. ) du t e x t e 48 dans l e s d i f f é r e n t s éléments d une page HTML au niveau de l en t ê t e. 49 </p> 50 <p> 51 Enfin, s i l on s o u h a i t e changer l e s t y l e localement pour d é c o r e r 52 sans qu i l s a g i s s e d un élément s t r u c t u r e l, on peut <strong style= font v a r i a n t :normal ; >s u r c h a r g e r l e s t y l e g l o b a l</strong> 53 localement. 54 On peut a u s s i u t i l i s e r<span style= font family :Comic Sans MS; font s i z e :150% > l a b a l i s e g é nérique &l t ; span&gt ;& l t ; / span&gt ;. </span> 55 pour m o d i f i e r localement l a s p ect du t e x t e sans m o d i f i e r l a s t r u c t u r e. 56 </p> 57 </body> <! f i n du corps HTML > 58 </html> <! f i n du code HTML > exemples/chapitrehtml/ex07_couleurs.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <style> 6 /* D é f i n i t i o n du s t y l e */ 7 body { 8 font s i z e : 125% ; 9 background c o l o r : #c0c0c0 ; /* f o n t e par défaut */ 10 c o l o r : # ; 11 font weight : bold 15

17 Rémy Malgouyres, Programmation Web 12 } 13 p { 14 text a l i g n : j u s t i f y ; 15 }/* mise en forme des paragraphes */ 16 /* mise en forme du t i t r e */ 17 h1 { 18 text a l i g n : c e n t e r ; 19 font s i z e : 150% ; 20 background c o l o r : #ddd ; 21 border s t y l e : s o l i d ; 22 border c o l o r : black ; 23 border width : 2px ; 24 } 25 /* mise en forme élémentt important l e s 120% sont r e l a t i f au contexte */ 26 strong { 27 background c o l o r : white ; 28 c o l o r : black ; 29 font weight : bolder ; 30 } 31 </ style> 32 <t i t l e>d é f i n i t i o n des c o u l e u r s</ t i t l e> 33 </head> 34 <body> 35 <h1> D é f i n i t i o n des c o u l e u r s dans dans un s t y l e CSS </h1> 36 <p> 37 Dans l e s t y l e CSS, on peut a u s s i d é f i n i r l e s c o u l e u r s des d i f f é r e n t s 38 éléments. 39 </p> 40 <p> 41 Les s i t e s web ont en g é n é r a l une <strong>c h a r t e graphique</strong> qui 42 comprend un p e t i t nombre de c o u l e u r s bien harmonisées qui symbolisent bien 43 l e n t i t é que r e p r é s e n t e l e s i t e. 44 </p> 45 <p> 46 Dans l e s e n t r e p r i s e s, ce sont souvent des personnes d i f f é r e n t e s qui 47 s occupent du s t y l e CSS ou qui s occupent du contenu et des f o n c t i o n a l i t é s 48 du s i t e. 49 </p> 16

18 Chapitre 1 : Pages web statiques HTML5 50 </body> 51 </html> 1.7 Formes d inclusion de styles CSS Il y a essentiellement 3 manières de modifier le style graphique des différents éléments d une page HTML en utilisant CSS : 1. Au niveau des balises HTML avec l option style="..." (style CSS local) ; 2. Au niveau du header de la page HTML avec la balise <style type="text/css"> (style CSS global) ; 3. En incluant une feuille de style qui se trouve dans un fichier.css séparée avec la balise <link/> au niveau du header HTML (style CSS global pouvant être inclus dans plusieurs pages d un même site) : <link rel="stylesheet" href="./my_style.css" /> Cela permet de définir son style CSS globalement pour tout un site, de manière que toutes les pages aient le même style graphique. Du fait que le style CSS est défini à un seul endroit, la maintenance est plus facile : il n y a qu un seul endroit à changer pour modifier l aspect de tout le site. 4. En ajoutant une feuille de style complémentaire au niveau du header HTML avec la directive CSS import url (style CSS global additionnel pouvant être inclus dans plusieurs pages d un même site) : url(./my_extra_style.css); </style> Cela permet d ajouter plusieurs feuilles de style à une même page, ce qui augmente la souplesse de l organisation des styles CSS. Pour le dernier exemple (sur les couleurs) de la partie 1.6, on peut par exemple obtenir la même chose en incluant le style CSS dans une feuille de style séparée : exemples/chapitrehtml/ex08_css_stylesheet_couleur.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>f e u i l l e s de S t y l e <i>css</ i></ t i t l e> 7 </head> 8 <body> 9 <h1> Créer une f e u i l l e de s t y l e CSS </h1> 10 <p> 17

19 Rémy Malgouyres, Programmation Web 11 Le s t y l e <i>css</ i> peut ê t r e d é f i n i dans un f i c h i e r <code>. c s s</code> séparé 12 du f i c h i e r <i>html</ i>. 13 </p> 14 <p> 15 Celà permet d augmenter l a modularité du code d un s i t e web car 16 l e s t y l e <i>css</ i> de t o u t e s l e s pages d un même s i t e peut ê t r e 17 d é f i n i à un s e u l e n d r o i t. 18 </p> 19 <p> 20 S i l f a u t changer l e s t y l e d un c e r t a i n type de b a l i s e s dans tout l e s i t e, 21 i l n y a qu un s e u l e n d r o i t à changer. ; ) 22 </p> 23 </body> 24 </html> exemples/chapitrehtml/mystyle.css 1 /* D é f i n i t i o n du s t y l e */ 2 body { 3 font family : A r i a l Verdana ; 4 font s i z e : 125% ; /* f a c t e u r d é v h e l l e sur l a t a i l l e g l o b a l e de l a p o l i c e */ 5 background c o l o r : #c0c0c0 ; /* f o n t e par défaut */ 6 c o l o r : # ; /* c o u l e u r du t e x t e g l o b a l e */ 7 } 8 /* mise en forme des paragraphes */ 9 p { 10 text a l i g n : j u s t i f y ; /* t e x t e j u s t i f i é dans l e s paragraphes */ 11 } 12 /* mise en forme du t i t r e */ 13 h1 { 14 text a l i g n : c e n t e r ; /* t e x t e c e n t r é */ 15 font s i z e : 150% ; /* f a c t e u r d é c h e l l e de l a p o l i c e */ 16 background c o l o r : #ddd ; /* c o u l e u r du fond */ 17 border s t y l e : s o l i d ; /* bordure en t r a i t p l e i n */ 18 border c o l o r : black ; /* c o u l e u r du bord */ 19 border width : 2px ; /* é p a i s s e u r du bord */ 20 border r a d i u s : 10px ; /* bordure a r r o n d i e */ 21 } 22 /* mise en forme élémentt important l e s 120% sont r e l a t i f au contexte */ 18

20 Chapitre 1 : Pages web statiques HTML5 23 strong { 24 c o l o r : black ; /* t e x t e n o i r */ 25 font weight : bolder ; /* extra gras */ 26 font v a r i a n t : small caps ; /* p e t i t e s c a p i t a l e s */ 27 } Dans la suite ce ce chapitre, nous inclurons dans toutes les pages HTML la feuille de style de ce dernier exemple. 1.8 Liens exemples/chapitrehtml/ex09_liens.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>liens hypertexte</ t i t l e> 7 </head> 8 <body> 9 <! début du corps HTML > 10 <h1>liens hypertexte</h1> 11 <div> 12 <strong>on peut c r é e r d i f f é r e n t s types de l i e n s :</strong> 13 <ul> 14 <! l i s t e à puces > 15 < l i> 16 l i e n s hypertexte en r e l a t i f : <a href=. / ex_images. html >c l i q u e z i c i< /a>. 17 </ l i> 19

21 Rémy Malgouyres, Programmation Web 18 < l i> 19 l i e n s hypertexte en absolu : <a href= http ://www. remysprogwebtuto. org / exemples /html/ex_images. html > c l i q u e z i c i</a>. 20 </ l i> 21 < l i> 22 l i e n s v e r s une ancre v e r s un autre emplacement dans l a page : <a href= #monparagraphe >Voir l e deuxième par ag rap he</a> 23 </ l i> 24 </ ul> 25 </ div> 26 <p id= monparagraphe style= font s i z e : 150% ; font weight : b older ; > 27 Pour f a i r e des l i e n s v e r s l e s i t e même, i l vaut t o u j o u r s mieux 28 u t i l i s e r des l i e n s en r e l a t i f s car s i on déménage l e s i t e ( ou 29 s i on r écupère c e r t a i n e s c l a s s e s ), l e s l i e n s ne c a s s e n t pas. 30 ( à c o n d i t i o n de garder l a r b o r e s c e n c e des r é p e r t o i r e s t e l l e q u e l l e ) 31 <br/> 32 &Eacute ; v i t e z l e s chemins du genre : 33 <br/> 34 <code> 35 C :/ j e / tourne / pas / sur /un/ s e r v e u r / l i n u x. html </code> 36 </p> 37 </body> 38 <! f i n du corps HTML > 39 </html> 40 <! f i n du code HTML > 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> exemples/chapitrehtml/ex10_liens_mise_en_forme.html 20

22 Chapitre 1 : Pages web statiques HTML5 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <style> 7 /* s t y l e par défaut des l i e n s */ 8 a : l i n k { 9 text d e c o r a t i o n : none ; 10 c o l o r : #00e ; /* bleu c l a i r */ 11 } 12 /* s t y l e des l i e n s v i s i t é s */ 13 a : v i s i t e d { 14 text d e c o r a t i o n : none ; 15 c o l o r : #c0c ;/* mauve */ 16 } 17 /* s t y l e des l i e n s v i s i t é s */ 18 a :hover { 19 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 20 c o l o r : #e40 ;/* rouge v i f */ 21 } 22 </ style> 23 <t i t l e>liens hypertexte ( 2 )</ t i t l e> 24 </head> 25 <body> 26 <! début du corps HTML > 27 <h1>mise en forme des l i e n s hypertexte</h1> 28 <div> 29 <strong>on peut c r é e r d i f f é r e n t s types de l i e n s :</strong> 30 <ul> 31 <! l i s t e à puces > 32 < l i> 33 l i e n s hypertexte en r e l a t i f : <a href=. / ex_images. html >c l i q u e z i c i< /a>. 34 </ l i> 35 < l i> 36 l i e n s hypertexte en absolu : <a href= http ://www. remysprogwebtuto. org / exemples /html/ex_images. html > c l i q u e z i c i</a>. 37 </ l i> 38 < l i> 39 l i e n s v e r s une ancre v e r s un autre emplacement dans l a page : <a href= #monparagraphe >Voir l e deuxième par ag rap he</a> 40 </ l i> 41 </ ul> 42 </ div> 43 <p id= monparagraphe style= font s i z e : 150% ; font weight : b older ; > 44 Pour f a i r e des l i e n s v e r s l e s i t e même, i l vaut t o u j o u r s mieux 45 u t i l i s e r des l i e n s en r e l a t i f s car s i on déménage l e s i t e ( ou 46 s i on r écupère c e r t a i n e s c l a s s e s ), l e s l i e n s ne c a s s e n t pas. 47 ( à c o n d i t i o n de garder l a r b o r e s c e n c e des r é p e r t o i r e s t e l l e q u e l l e ) 48 <br/> 49 &Eacute ; v i t e z l e s chemins du genre : 50 <br/> 51 <code> 52 C :/ j e / tourne / pas / sur /un/ s e r v e u r / l i n u x. html </code> 53 </p> 54 </body> 55 <! f i n du corps HTML > 56 </html> 57 <! f i n du code HTML > 21

23 Rémy Malgouyres, Programmation Web 1.9 Tableaux exemples/chapitrehtml/ex11_tableaux.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>tableaux en HTML</ t i t l e> 7 </head> 8 <body> 9 <! début du corps HTML > 10 <h1>tableaux en HTML 5</h1> <p> 13 Voici une t a b l e avec l e s t y l e par défaut. Le rendu e s t un peu sommaire. 14 </p> 15 <table> 16 <caption> <! Légende ( t i t r e ) de l a table > 17 Exemple de t a b l e sans mise en forme 18 </ caption> 19 <tbody><! corps de l a table > 20 <tr><! n o u v e l l e l i g n e > 21 <td><! n o u v e l l e case > 22 Ceci e s t l a case<br/>d en haut à gauche 23 </ td> 24 <td><! n o u v e l l e case > 25 Ceci e s t l a case<br/>d en haut au m i l i e u 26 </ td> 27 <td><! n o u v e l l e case > 28 Ceci e s t l a case<br/>d en haut à d r o i t e 29 </ td> 30 </ tr> 31 <tr> <! n o u v e l l e l i g n e > 32 <td><! n o u v e l l e case > 33 Ceci e s t l a case<br/>d en bas à gauche 34 </ td> 35 <td><! n o u v e l l e case > 36 Ceci e s t l a case<br/>d en bas au m i l i e u 22

24 Chapitre 1 : Pages web statiques HTML5 37 </ td> 38 <td><! n o u v e l l e case > 39 Ceci e s t l a case<br/>d en bas à d r o i t e 40 </ td> 41 </ tr> 42 </tbody> 43 </ table> 44 </body><! f i n du corps HTML > 45 </html> 46 <! f i n du code HTML > exemples/chapitrehtml/ex12_tableaux_th.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>tableaux en HTML ( 2 )</ t i t l e> 7 </head> 8 <body> 9 <! début du corps HTML > 10 <h1>tableaux : en t ê t e de l i g n e s et de c o l o n n e s</h1> <p> 13 Voici une t a b l e avec l e s t y l e par défaut et avec des en t ê l e ( t i t r e s ) de l i g n e et colonne. 14 </p> 15 <table> 16 <caption> 17 Exemple de t a b l e sans mise en forme 18 </ caption> 19 <thead><! En t ê t e de l a table > 20 <tr><! n o u v e l l e l i g n e ( l i g n e de t i t r e s de colonnes ) > 21 <th ></th><! case v i d e en haut à gauche > 22 <th ><strong>colonne 1</ strong></ th> 23 <th><strong>colonne 2</ strong></ th> 23

25 Rémy Malgouyres, Programmation Web 24 <th><strong>colonne 3</ strong></ th> 25 </ tr> 26 </thead> 27 <tbody><! corps de l a table > 28 <tr> <! n o u v e l l e l i g n e > 29 <th ><! t i t r e de l i g n e > 30 <strong>l i g n e&nbsp ; 1</strong> 31 </ th> 32 <td><! n o u v e l l e case > 33 Ceci e s t l a case<br/> 34 d en haut à gauche 35 </ td> 36 <td><! n o u v e l l e case > 37 Ceci e s t l a case<br/> 38 d en haut au m i l i e u 39 </ td> 40 <td><! n o u v e l l e case > 41 Ceci e s t l a case<br/> 42 d en haut à d r o i t e 43 </ td> 44 </ tr> 45 <tr><! n o u v e l l e l i g n e > 46 <th><! t i t r e de l i g n e > 47 <strong>l i g n e&nbsp ; 2</strong> 48 </ th> 49 <td><! n o u v e l l e case > 50 Ceci e s t l a case<br/> 51 d en bas à gauche 52 </ td> 53 <td><! n o u v e l l e case > 54 Ceci e s t l a case<br/> 55 d en bas au m i l i e u 56 </ td> 57 <td><! n o u v e l l e case > 58 Ceci e s t l a case<br/> 59 d en bas à d r o i t e 60 </ td> 61 </ tr> 62 </tbody> 63 </ table> 64 </body><! f i n du corps HTML > 65 </html> 66 <! f i n du code HTML > exemples/chapitrehtml/ex13_tableaux_mise_en_forme.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <style> u r l (. / ex13_stylesheet_tableaux. c s s ) ; 8 </ style> 9 <t i t l e>tableaux en HTML ( 3 )</ t i t l e> 10 </head> 24

26 Chapitre 1 : Pages web statiques HTML5 11 <body> 12 <! début du corps HTML > 13 <h1>tableaux : mise en forme</h1> 14 <table> 15 <caption> 16 Exemple de t a b l e avec mise en forme 17 </ caption> 18 <thead><! En t ê t e de l a table > 19 <tr><! n o u v e l l e l i g n e ( l i g n e de t i t r e s de colonnes ) > 20 <th style= border r a d i u s : 10px ></th><! case v i d e en haut à gauche > 21 <th >Colonne 1</ th> 22 <th>colonne 2</ th> 23 <th style= border r a d i u s : 0 10px 0 0 >Colonne 3</th> 24 </ tr> 25 </thead> 26 <tbody><! corps de l a table > 27 <tr> <! n o u v e l l e l i g n e > 28 <th ><! t i t r e de l i g n e > 29 l i g n e&nbsp ; 1 30 </ th> 31 <td><! n o u v e l l e case > 32 Ceci e s t l a case<br/> 33 d en haut à gauche 34 </ td> 35 <td><! n o u v e l l e case > 36 Ceci e s t l a case<br/> 37 d en haut au m i l i e u 38 </ td> 39 <td><! n o u v e l l e case > 40 Ceci e s t l a case<br/> 41 d en haut à d r o i t e 42 </ td> 25

27 Rémy Malgouyres, Programmation Web 43 </ tr> 44 <tr><! n o u v e l l e l i g n e > 45 <th style= border r a d i u s : px ><! t i t r e de l i g n e > 46 l i g n e&nbsp ; 2 47 </ th> 48 <td><! n o u v e l l e case > 49 Ceci e s t l a case<br/> 50 d en bas à gauche 51 </ td> 52 <td><! n o u v e l l e case > 53 Ceci e s t l a case<br/> 54 d en bas au m i l i e u 55 </ td> 56 <td style= border r a d i u s : px 0 ><! n o u v e l l e case > 57 Ceci e s t l a case<br/> 58 d en bas à d r o i t e 59 </ td> 60 </ tr> 61 </tbody> 62 </ table> 63 <p> 64 <strong>remarque.</strong> La p r o p r i é t é <i>css</ i> <code>border r a d i u s</ code> permet de c r é e r 65 des a n g l e s a r r o n d i s pour l e s bordures. E l l e peut se d é f i n i r globalement pour l e s 4 a n g l e s 66 ( v o i r i c i l e s t y l e de l a b a l i s e &l t ; t a b l e&gt ; dans l a f e u i l l e de s t y l e des tableaux ) 67 du bord ou bien i n d i v i d u e l l e m e n t pour chaque angle ( v o i r i c i l e s s t y l e s locaux sur &l t ; th&gt ; et &l t ; td&gt ; ). 68 </p> 69 </body><! f i n du corps HTML > 70 </html> 71 <! f i n du code HTML > exemples/chapitrehtml/ex13_stylesheet_tableaux.css 1 /** FEUILLE DE STYLE COMPLÉMENTAIRE POUR MISE EN FORME DES TABLEAUX **/ 2 t a b l e { /* mise en forme des t a b l e s */ s 3 background c o l o r : #ddd ; /* fond g r i s */ 4 /* Paramètres ombrage : bas, d r o i t e, dégradé, c o u l e u r */ 5 box shadow : 8px 8px 22 px #000 ; /* Ombrage aux b ord s de l a t a b l e */ 6 border width : 3px ; /* é p a i s s e u r du t r a i t pour l e bord */ 7 border s t y l e : s o l i d ; /* bord en t r a i t continu */ 8 border c o l o r : black ; /* c o u l e u r du bord */ 9 border r a d i u s : 10px ; 10 } 11 caption { 12 c o l o r :red ; 13 font s i z e :130% ; 14 } 15 t r td { /* mise en forme des c e l l u l e s */ 16 border s t y l e : dashed ; /* bord en p o i n t i l l é s */ 17 border width : 2px ; /* é p a i s s e u r du t r a i t pour l e bord */ 18 border c o l o r : black ; /* c o u l e u r du bord */ 19 background c o l o r : white ;/* fond blanc */ 20 c o l o r : black ; /* c o u l e u r du t e x t e */ 26

28 Chapitre 1 : Pages web statiques HTML5 21 text a l i g n :center ; /* t e x t e c e n t r é */ 22 padding : 20px ; /* espace e n t r e l e t e x t e et l e bord de l a c e l l u l e */ 23 } 24 th {/* mise en forme des en t ê t e de l i g n e et colonne */ 25 border s t y l e : s o l i d ; /* bord en t r a i t continu */ 26 border width : 2px ; /* é p a i s s e u r du t r a i t pour l e bord */ 27 border c o l o r : black ; /* c o u l e u r du bord */ 28 text a l i g n :center ; /* t e x t e c e n t r é */ 29 font weight : bolder ; /* c a r a c t è r e s gras appuyé */ 30 c o l o r : black ; /* c o u l e u r du t e x t e */ 31 padding : 20px ; /* espace e n t r e l e t e x t e et l e bord de l a c e l l u l e */ 32 } 1.10 Insertion d images Avant d insérer des images dans un site web, des retouches de l image sont souvent nécessaires : 1. L usage veut que l on essaie de réduire le poids en octets de l image, soit en réduisant le nombre de pixels par redimensionnement de l image, soit en compressant plus fortement l images (paramètre d enregistrement JPEG ou PNG) lorsque c est possible sans dégrader la qualité. 2. Il faut souvent mettre un fond transparent pour l image si l on veut l incruster sur un fond en couleur. 3. Il faut parfois éclaircir ou foncer l image pour faire ressortir le contraste avec le texte incrusté dessus. 4. Il faut parfois retoucher les couleurs pour les adapter à la charte graphique. Le logiciel open-source GIMP permet de réaliser toutes ces opérations (facilement avec un peu d habitude). 27

29 Rémy Malgouyres, Programmation Web exemples/chapitrehtml/ex14_images.html 1 <! doctype html> 2 <html lang= f r > 3 <head > 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>i n s e r t i o n d images en HTML</ t i t l e> 7 </head> 8 <body> <! début du corps HTML > 9 <h1>i n s e r t i o n d images en HTML</h1> 10 <p> 11 On i n s è r e l e s images avec l a b a l i s e &l t ; img&gt ;&nbsp ; :<br/> 12 </p> 13 <p style= text a l i g n : c e n t e r ; > <img src=. / p i c /gimp. png alt= The GIMP Logo width= style= v e r t i c a l a l i g n : middle ; 18 /> 19 <img src=. / p i c /3d gnu head_petit. png width= alt= The GNU Logo 21 style= v e r t i c a l a l i g n : middle ; 22 /> 23 </p> 24 <p> 25 On peut r e t o u c h e r l e s images avec l e l o g i c i e l GNU GIMP<br/> 26 voyez l a 27 <a href=. / p i c / capture_gimp. png >capture d écran</a> montrant 28 comment diminuer l e nombre de p i x e l s d une image pour en diminuer l e 29 poids ( en megaoctets ). 30 </p> </body> <! f i n du corps HTML > 33 </html> <! f i n du code HTML > 1 <! doctype html> 2 <html lang= f r > exemples/chapitrehtml/ex15_images_avec_click.html 28

30 Chapitre 1 : Pages web statiques HTML5 3 <head > 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>click sur une image en HTML</ t i t l e> 7 </head> 8 <body> <! début du corps HTML > 9 <h1>c l i c k s u r une image en HTML</h1> 10 <p> 11 On i n s è r e l e s images avec l a b a l i s e &l t ; img&gt ;&nbsp ; :<br/> 12 </p> 13 <p style= text a l i g n : c e n t e r ; > 14 Cliquez sur l e GNU pour l e v o i r en grand :<br/> 15 <img src=. / p i c /gimp. png alt= The GIMP Logo width= style= v e r t i c a l a l i g n : middle ; 17 /> 18 <a href=. / p i c /3d gnu head_fond_transp. png > 19 <img src=. / p i c /3d gnu head_petit. png width= alt= The GNU Logo 21 style= v e r t i c a l a l i g n : middle ; 22 /> 23 </a> 24 </p> </body> <! f i n du corps HTML > 27 </html> <! f i n du code HTML > 1.11 Figures et sous-figures avec légende 1 <! doctype html> exemples/chapitrehtml/ex16_figure.html 29

31 Rémy Malgouyres, Programmation Web 2 <html lang= f r > 3 <head > 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>figures avec l é g e n d e s en HTML</ t i t l e> 7 </head> 8 <body> <! début du corps HTML > 9 <h1>figures avec légende en HTML</h1> 10 <p> 11 On c r é e une f i g u r e contenant une image avec l a b a l i s e &l t ; f i g u r e&gt ;&nbsp ; :<br/> 12 </p> 13 <f i g u r e style= text a l i g n :center ; > 14 <img src=. / p i c /gimp. png alt= The GIMP Logo width= style= v e r t i c a l a l i g n : middle ; 16 /> 17 <f i g c a p t i o n>le Logo de <i>gimp</ i></ f i g c a p t i o n> 18 </ f i g u r e> 19 <f i g u r e style= text a l i g n :center ; > 20 <img src=. / p i c /3d gnu head_petit. png width= alt= The GNU Logo 22 style= v e r t i c a l a l i g n : middle ; 23 /> 24 <f i g c a p t i o n>le Logo de <i>gnu</ i></ f i g c a p t i o n> 25 </ f i g u r e> 26 </body> <! f i n du corps HTML > 27 </html> <! f i n du code HTML > exemples/chapitrehtml/ex17_subfigure.html 1 <! doctype html> 2 <html lang= f r > 3 <head > 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 30

32 Chapitre 1 : Pages web statiques HTML5 6 <t i t l e>sous f i g u r e s avec l é g e n d e s en HTML</ t i t l e> 7 </head> 8 <body> <! début du corps HTML > 9 <h1>sous f i g u r e s avec l é g e n d e s en HTML</h1> 10 <p> 11 On c r é e des sous f i g u r e s en imbriquant b a l i s e s &l t ; f i g u r e&gt ;&nbsp ; :<br/> 12 On peut f a i r e en s o r t e que l e s f i g u r e s se mettent l une à c ôté de l autre avec 13 l a p r o p r i é t é <i>css</ i> <code> d i s p l a y : i n l i n e block ; </code>. 14 </p> 15 <f i g u r e style= text a l i g n :center ; > 16 <f i g u r e style= d i s p l a y : i n l i n e block ; > 17 <img src=. / p i c /gimp. png alt= The GIMP Logo width= style= v e r t i c a l a l i g n : middle ; 19 /> 20 <f i g c a p t i o n><b>( a )</b> Le Logo de <i>gimp</ i></ f i g c a p t i o n> 21 </ f i g u r e> 22 <f i g u r e style= d i s p l a y : i n l i n e block ; > 23 <img src=. / p i c /3d gnu head_petit. png width= alt= The GNU Logo 25 style= v e r t i c a l a l i g n : middle ; 26 /> 27 <f i g c a p t i o n><b>( b )</b> Le Logo de <i>gnu</ i></ f i g c a p t i o n> 28 </ f i g u r e> 29 <f i g c a p t i o n><b>figure 1.</b> Exemples de l o g o s de l o g i c i e l s ou l i c e n c e s Open Source</ f i g c a p t i o n> 30 </ f i g u r e> 31 </body> <! f i n du corps HTML > 32 </html> <! f i n du code HTML > 1.12 Caractères spéciaux De nos jours les accents dans certains langues comme le français sont pris en compte sans problème par le standard unicode UTF (par exemple UTF-8). On peut donc sans crainte taper des accents au clavier dans un éditeur HTML. Certains caractères spéciaux, tels que les caractères qui ont une signification particulière dans le langage HTML (comme < et >), doivent cependant être représentée par une séquence d échappement (commençant par & et terminant par ;). De nombreuses pages recenssent ces séquences d échappement sur le web : 31

33 Chapitre 2 Styles CSS et mise en page 2.1 Éléments HTML de type block et inline Avant d étudier plus avant les styles CSS, nous devons en dire un peu plus sur la structuration des pages HTML. On distingue en HTML dans catégories d éléments : les éléments de type block et les éléments de type inline. Ces deux sortes d éléments ne se comportent pas de la même manière quand à leur positionnement dans la page : Éléments blocks exemples/chapitrecss/ex01_blocks.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>éléments de type block </ t i t l e> 32

34 Chapitre 2 : Styles CSS et mise en page 7 </head> 8 <body> 9 <h1>éléments de type block </h1> 10 <p> 11 I l e x i s t e en XHTML deux principaux types de b a l i s e s&nbsp ; : i n l i n e ou block. 12 </p> 13 <o l> 14 < l i> 15 <strong>exemples de b a l i s e s de type block&nbsp ; :</strong> 16 <br/> 17 <ol type= a > 18 < l i> 19 &l t ; p&gt ;&nbsp ; : nouveau paragraphe&#59 ; 20 </ l i> 21 < l i> 22 &l t ; t a b l e&gt ;&nbsp ; : tableau contenant des donnée&#59 ; 23 </ l i> 24 < l i> 25 &l t ; h1&gt ;&nbsp ;,..., &l t ; h6&gt ;&nbsp ; : d i f f é r e n t s 26 niveaux de t i t r e &#59 ; 27 </ l i> 28 < l i> 29 &l t ; dl&gt ;&nbsp ; : l i s t e de d é f i n i t i o n &#59 ; 30 </ l i> 31 < l i> 32 &l t ; ul&gt ;&nbsp ; : l i s t e non ordonnée&#59 ; 33 </ l i> 34 < l i> 35 &l t ; o l&gt ;&nbsp ; : l i s t e ordonnée&#59 ; 36 </ l i> 37 < l i> 38 &l t ; pre&gt ;&nbsp ; : i n s e r t i o n de code ( preformated t e x t ) verbatim 39 en p o l i c e t y p e w r i t e r avec r e s p e c t de l i n d e n t a t i o n. 40 </ l i> 41 </ ol> 42 Ces b a l i s e s changent l apparence de l e u r contenu et l e u r nature 43 au niveau s t r u c t u r e l et éventuellement l e u r f o n c t i o n dans l e cas du l i e n 44 ou de l image. 45 <br/> 46 En <i>html5</ i>, on trouve a u s s i l e s b a l i s e s sémantiques &l t ; header&gt ;, &l t ; f o o t e r&gt ;, &l t ; nav&gt ;, e t c. que nous verrons plus l o i n. 47 </ l i> 48 </ ol> 49 </body> 50 </html> Lors de l insertion d un élément de type block dans un document HTML, l élément va (par défaut) à la ligne : l élément est inséré aligné à gauche sous l élément précédent Éléments inline 1 <! doctype html> exemples/chapitrecss/ex02_inline.html 33

35 Rémy Malgouyres, Programmation Web 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>éléments de type i n l i n e </ t i t l e> 7 </head> 8 <body> 9 <h1>éléments de type i n l i n e </h1> 10 <ol s t a r t= 2 > 11 < l i><strong>exemples de b a l i s e s en l i g n e ou i n l i n e &nbsp ; :</strong></ l i> 12 <ol type= a > 13 < l i>&l t ; span&gt ;&nbsp ; : changement l o c a l de s t y l e&nbsp ;&#59 ;</ l i> 14 < l i>&l t ; a&gt ;&nbsp ; : l i e n hypertexte&#59 ;</ l i> 15 < l i>&l t ; strong&gt ;&nbsp ; : élément important&#59 ;</ l i> 16 < l i>&l t ; em&gt ;&nbsp ; : élément à s o u l i g n e r &#59 ;</ l i> 17 < l i>&l t ; q&gt ;&nbsp ; : c i t a t i o n c o u r t e&#59 ;</ l i> 18 < l i>&l t ; code&gt ;&nbsp ; : t e x t e en p o l i c e <code>t y p e w r i t e r</code></ l i> 19 </ ol> 20 Ces b a l i s e s changent l apparence de l e u r contenu mais pas l e u r nature 21 au niveau s t r u c t u r e l ni l e u r p o s i t i o n dans l e document. 22 </ l i> 23 </ ol> 24 <p> 25 Tout élément i n l i n e d o i t ê t r e contenu dans au moins un block. Le b l o c k s peuvent 26 ê t r e imbriqués mais l e s b l o c k s &l t ; p&gt ;&nbsp ; et l e s b l o c k s t i t r e 27 &l t ; h1&gt ;&nbsp ;,..., &l t ; h6&gt ;&nbsp ; ne peuvent c o n t e n i r d a u t r e s b l o c k s.< br/> 28 Un élément i n l i n e ne peut c o n t e n i r aucun élément de type block ; 29 </p> 30 </body> 31 </html> Lors de l insertion d un élément de type inline dans un document HTML, l élément s insère (par défaut) à la suite sur la même ligne : l élément est inséré aligné à la suite de l élément précédent sur la même ligne, ou à la ligne suivante s il n y a plus de place sur la ligne. 34

36 Chapitre 2 : Styles CSS et mise en page Le flux et la propriété CSS display Le positionnement par défaut des éléments de type block ( à la ligne ) et inline ( à la suite sur la même ligne ) s appelle la position dans le flux. La propriété CSS display permet de modifier la place dans le flux des éléments : display: none : L élément est purement et simplement supprimé du flux, comme s il n existait pas. Cela permet de faire apparaître ou disparaître des éléments suivants des événements, par exemple des événements Javascript. On peut ainsi créer des popups, etc... display: inline : l élément est inséré comme s il s agissait d un élément de type inline ; display: block : l élément est inséré comme s il s agissait d un élément de type block ; display: inline-block : Ces éléments peuvent contenir d autres éléments de type block ou inline. Ils s insèrent dans le flux comme des éléments inline : à la suite sur la même ligne. exemples/chapitrecss/ex03_propriete_display.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>p r o p r i é t é d i s p l a y</ t i t l e> 7 </head> 8 <body> 9 <h1>p r o p r i é t é d i s p l a y</h1> 10 <p style= border s t y l e : groove ; d i s p l a y : i n l i n e block ; v e r t i c a l a l i g n : middle ; > 11 Ce premier paragraphe,<br/>avec un bord en t r a i t 3D, 12 <br/>e s t un paragraphe en i n l i n e block. 13 </p> 35

37 Rémy Malgouyres, Programmation Web 14 <p style= border s t y l e : dashed ; d i s p l a y : i n l i n e block ; v e r t i c a l a l i g n : middle ; > 15 Ce second paragraphe, <br/>avec un bord en t i r e t s, 16 <br/>e s t un paragraphe en i n l i n e bloc. 17 </p> 18 <p style= border s t y l e : s o l i d ; d i s p l a y : block ; v e r t i c a l a l i g n : middle ; > 19 Ce t r o i s i è m e paragraphe, <br/>avec un bord en t r a i t p l e i n, 20 <br/>e s t un paragraphe normal de type block. 21 </p> 22 <p style= border s t y l e : s o l i d ; d i s p l a y : none ; v e r t i c a l a l i g n : middle ; > 23 Ce quatrième paragraphe, <br/>avec un bord en t r a i t p l e i n, 24 <br/>e s t un paragraphe en d i s p l a y : none ( non a f f i c h é! ). 25 </p> 26 <p style= border s t y l e : dotted ; d i s p l a y : i n l i n e ; v e r t i c a l a l i g n : middle ; > 27 Ce cinquième paragraphe, <br/>avec un bord en p o i n t i l l é s, 28 <br/>e s t un paragraphe en i n l i n e. 29 </p> 30 </body> 31 </html> 2.2 Distinguer des parties dans un document : balise div exemples/chapitrecss/ex04_div.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>la B a l i s e &l t ; div&gt ;</ t i t l e> 7 </head> 8 <body> 36

38 Chapitre 2 : Styles CSS et mise en page 9 <h1>d i s t i n g u e r des p a r t i e s dans l a page&nbsp ; :<br/>la b a l i s e &l t ; div&gt ;</h1 > 10 <div style= background c o l o r : #f85 > 11 <p> 12 <b>1)</b> Un élément &l t ; div&gt ; e s t une p a r t i e d un document <i>html</ i >. 13 La b a l i s e &l t ; div&gt ; e s t ( par défaut ) de type block. 14 </p> 15 <p> 16 Contrairement aux paragraphes, un &l t ; div&gt ; peut c o n t e n i r d a u t r e s b a l i s e s 17 de type block comme d a u t r e s &l t ; div&gt ;, des paragraphes, des tableaux, e t c. 18 </p> 19 </ div> 20 <div style= background c o l o r :white ; > 21 <p> 22 <b>2)</b> Le &l t ; div&gt ; d i f f è r e d un &l t ; span&gt ; en c e c i que l e span e s t 23 ( par défaut ) de type i n l i n e et 24 <span style= background c o l o r : black ; c o l o r : white ; border r a d i u s : 5px ; > 25 l e &l t ; span&gt ; ne modifie pas vraiment l a s t r u c t u r e du document 26 </span>. 27 I l donne j u s t e un s t a t u t ou un s t y l e p a r t i c u l i e r à une c e r t a i n e étendue du document. 28 </p> 29 <p> 30 Le &l t ; div&gt ;, au c o n t r a i r e, permet de <strong>d i v i s e r</strong> l e document en 31 p a r t i e s qui peuvent ê t r e d i s p o s é e s au gré de l a f a n t a i s i e du d e s i g n e r. 32 Le &l t ; div&gt ; e s t l a base de l a d i v i s i o n des pages en d i f f é r e n t e s p a r t i e s. 33 </p> 34 </ div> 35 </body> 36 </html> 2.3 Imbrication des balises et CSS exemples/chapitrecss/ex05_imbrication_balises_et_css.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <style> 7 body p{ 8 background c o l o r : #777 ; 9 c o l o r : white ; 10 } 11 body div p{ 12 background c o l o r : #eee ; 37

39 Rémy Malgouyres, Programmation Web 13 c o l o r : #111 ; 14 } 15 body div div p{ 16 background c o l o r : #111 ; 17 c o l o r : #eee ; 18 } 19 </ style> 20 <t i t l e>i m b r i c a t i o n des b a l i s e s et <i>css</ i></ t i t l e> 21 </head> 22 <body> 23 <h1>i m b r i c a t i o n des b a l i s e s et <i>css</ i></h1> 24 <p> 25 Les b a l i s e s peuvent ( moyennant c e r t a i n s c o n t r a i n t e s sur l i m b r i c a t i o n des b l o c k s ) 26 s imbriquer l e s unes dans l e s a u t r e s. I c i un paragraphe imbriqué directement 27 dans l e &l t ; body&gt ;.<br/> 28 C e s t l e s t y l e <code>body p</code> qui s applique i c i. 29 </p> 30 <div> 31 <p> 32 Le s t y l e <i>css</ i> des éléments peut ê t r e r é g l é différemment s uivant l e u r 33 i m b r i c a t i o n dans d a u t r e s b a l i s e s. I c i un paragraphe imbriqué dans un & l t ; div&gt ; 34 l u i même imbriqué directement dans l e &l t ; body&gt ;.<br/> 35 C e s t l e s t y l e <code>body div p</code> qui s applique i c i. 36 </p> 37 <p> 38 I c i un autre paragraphe imbriqué dans un &l t ; div&gt ; 39 l u i même imbriqué directement dans l e &l t ; body&gt ;.<br/> 40 C e s t l e s t y l e <code>body div p</code> qui s applique i c i. 41 </p> 42 </ div> 38

40 Chapitre 2 : Styles CSS et mise en page 43 <div> 44 <p> 45 I c i encore un autre paragraphe imbriqué dans un &l t ; div&gt ; 46 l u i même imbriqué directement dans l e &l t ; body&gt ;.<br/> 47 C e s t l e s t y l e <code>body div p</code> qui s applique i c i. 48 </p> 49 <div> 50 <p> 51 I c i on a un paragraphe imbriqué dans un &l t ; div&gt ; 52 l u i même dans un &l t ; div&gt ; imbriqué directement dans l e &l t ; body&gt ;.<br/> 53 C e s t l e s t y l e <code>body div div p</code> qui s applique i c i. 54 </p> 55 </ div> 56 </ div> 57 </body> 58 </html> 2.4 Arborescence de balises et CSS L imbrication des balises HTML d un document crée une arborescence, où une balise B 1 est fille d une autre balise B 2 si la balise B 1 est immédiatement imbriquée dans B 2 dans le document (voir la figure 2.1). body div h1 p div ul a p li span Figure 2.1 : L arbre d imbrication des balises de l exemple ex11_arborescencecss_html Dans le fichier CSS, on peut définir un style (et éventuellement plusieurs classes CSS) pour chaque sous-arbre de l arborescence. Pour cela, on indique le sous-arbre par la succession des noeuds de la racine de l arbre vers la racine du sous-arbre (voir exemple ci-dessous). 39

41 Rémy Malgouyres, Programmation Web exemples/chapitrecss/ex06_arborescencecss.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / ex06_arborescencecss. c s s /> 6 <t i t l e>arborescence de b a l i s e s</ t i t l e><t i t l e>arborescence de b a l i s e s et CSS< / t i t l e> 7 </head> 8 <body> 9 <h1>t i t r e p r i n c i p a l</h1> 10 <p> 11 f e u i l l e 1 12 <a href=. / my_url. html > f e u i l l e 2</a> 13 </p> 14 <div> 15 <div> 16 <p> 17 noeud 3 <span> f e u i l l e 4</span> 18 <p> 19 </ div> 20 </ div> 21 <div> 22 <ul> 23 < l i> 24 f e u i l l e 5 25 </ l i> 26 < l i> 27 f e u i l l e 6 28 </ l i> 29 </ ul> 30 </ div> 31 </body> 32 </html> 1 /* s t y l e par défaut du t e x t e */ 2 body { 3 font family : times, s e r i f ; 4 font s i z e :14 pt ; 5 background c o l o r : #ccc ; 6 c o l o r : #222 ; 7 } exemples/chapitrecss/ex06_arborescencecss.css 40

42 Chapitre 2 : Styles CSS et mise en page 8 9 h1 { 10 text a l i g n : c e n t e r ; 11 } div { 14 background c o l o r : #f f 0 ; 15 } p { background c o l o r : white ; } p a { text d e c o r a t i o n : o v e r l i n e ; } div div p { 30 c o l o r : red ; 31 text a l i g n : c e n t e r ; 32 background c o l o r : #ddd ; } div div p span { 38 font family : Comic Sans MS; 39 font s i z e :18 pt ; 40 } div ul { 44 background c o l o r : #0 f f ; 45 c o l o r : red ; 46 } 2.5 Classes CSS Les classes CSS permettent d appliquer un style CSS différent à différentes catégories (ou classes, que l on distingue pour un même type de balises HTML. exemples/chapitrecss/ex07_classes_css.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / ex07_classes_css. c s s /> 6 <t i t l e>c l a s s e s CSS</ t i t l e> 7 </head> 8 <body> 41

43 Rémy Malgouyres, Programmation Web 9 <h1>c l a s s e s CSS</h1> 10 <p class= l a b e l > 11 Menu : 12 </p> 13 <ol class= menu > 14 < l i> 15 <a class= boutton ombre href= #part1 >Qu est ce que c l a s s e s <i>css</ i> &nbsp ;?</a> 16 </ l i> 17 < l i> 18 <a class= boutton ombre href= #part2 >À quoi ça s e r t&nbsp ;?</a> 19 </ l i> 20 < l i> 21 <a class= boutton ombre href= #part2 >Exemple d usage</a> 22 </ l i> 23 </ ol> 24 <h2 id= part1 ><b>1)</b> Qu est ce que c l a s s e s <i>css</ i>&nbsp ;?</h2> 25 <p > 26 Les c l a s s e s permettent de d é f i n i r p l u s i e u r s c l a s s e s de c o n t e x t e s 27 dans l e s q u e l s l e s mises en formes sont d i f f é r e n t e s ( v o i r <a class= normallink href= #part2 >p a r t i e&nbsp ; 2</a>) 28 </p> 29 <h2 id= part2 ><b>2)</b> À quoi ça s e r t&nbsp ;?</h2> 30 <p> 31 Ainsi, des éléments qui ont l e même niveau d i m b r i c a t i o n dans l e s b a l i s e s 32 pourront a v o i r un s t y l e d i f f é r e n t s e l o n l e u r usage. 33 </p> 34 <h2 id= part3 ><b>3)</b> Exemple d usage</h2> 35 <p> 36 Par exemple, pour l e s l i e n s&nbsp ; 37 </p> 38 <o l> 42

44 Chapitre 2 : Styles CSS et mise en page 39 < l i>l e s l i e n s dans un menu pourront a v o i r l e s t y l e d un bouton,</ l i> 40 < l i>a l o r s que l e s l i e n s dans un a r t i c l e auront un aspect bleu s o u l i g n é,</ l i> 41 < l i> 42 ou e n c o r e l e s l i e n s v e r s l e s sponsors dans l e pied de page auront encore 43 un autre aspect. 44 </ l i> 45 </ ol> 46 </body> 47 </html> exemples/chapitrecss/ex07_classes_css.css 1 2 /* s t y l e par défaut du t e x t e */ 3 body { 4 font family : Comic Sans MS ; 5 font s i z e : 18 pt ; 6 background c o l o r : #f f f ; 7 c o l o r : #222 ; 8 } 9 10 /* s t y l e du t i t r e */ 11 h1 { 12 font weight : bold ; 13 font s i z e : 150% ; 14 c o l o r : white ; 15 text a l i g n : c e n t e r ; 16 background image : l i n e a r g r a d i e n t ( black, #bbb ) ; 17 padding : 15 pt ; 18 } h2 { 21 font weight : bold ; 22 font s i z e : 120% ; 23 } p{ 26 tex a l i g n : j u s t i f y ; 27 } p. l a b e l { 30 d i s p l a y : i n l i n e ; 31 background c o l o r : t r a n s p a r e n t ; 32 } /* s t y l e des éléments importants */ 35 strong { 36 font v a r i a n t : small caps ; 37 font weight : bolder ; 38 c o l o r : black ; 39 } strong. i n s i s t { 42 font s i z e : 130% ; 43

45 Rémy Malgouyres, Programmation Web 43 } strong. warning { 46 font s i z e : 150% ; 47 c o l o r : red ; 48 text d e c o r a t i o n : b l i n k ; 49 } /* s t y l e des éléments mis en évidence */ 52 em { 53 font s t y l e : i t a l i c ; 54 c o l o r : black ; 55 } p { 58 background c o l o r : #ddd ; 59 text a l i g n : j u s t i f y ; 60 padding : 5 pt ; 61 } /* s t y l e par défaut des l i e n s */ 64 a { 65 c o l o r : blue ; 66 text d e c o r a t i o n : u n d e r l i n e ; /* non s o u l i g n é */ 67 } o l. menu{ 70 d i s p l a y : i n l i n e block ; 71 } 72 o l. menu l i { 73 d i s p l a y : i n l i n e block ; 74 } 75 /* s t y l e de l i e n s s p é c i a l pour l a t a b l e des m a t i è r e s */ 76 a. boutton ombre { 77 c o l o r : white ; 78 border s t y l e : groove ; 79 border width : 3px ; 80 background c o l o r : #333 ; 81 text d e c o r a t i o n : none ; /* s u r l i g n é */ 82 padding : 5px ; 83 border r a d i u s : 15px ; 84 box shadow : 10 px 20 px 5px #777 ; 85 } exemples/chapitrecss/ex08_classes_css_tableaux.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <! I n c l u s i o n de s t y l e s s u p p l é m e n t a i r e s avec import > 7 <style> u r l ( ex08_classes_css_tableaux. c s s ) ; 9 </ style> 10 <t i t l e>s t y l e CSS de Tableaux</ t i t l e> 44

46 Chapitre 2 : Styles CSS et mise en page 11 </head> 12 <body> 13 <! début du corps HTML > 14 <h1>s t y l e <i>css</ i> de Tableaux</h1> <div style= margin : 0 auto ; width : 800px ; > 17 <table> 18 <caption> 19 Exemple de t a b l e 20 </ caption> 21 <thead> 22 <tr> 23 <th class= impair >Colonne 1</th> 24 <th class= p a i r >Colonne 2</th> 25 <th class= impair >Colonne 3</th> 26 <th class= p a i r >Colonne4</th> 27 </ tr> 28 </thead> 29 <tbody> 30 <tr> 31 <td class= p a i r >Ceci e s t l a case&nbsp ; 1</td> 32 <td class= impair >Ceci e s t l a case &nbsp ; 2</td> 33 <td class= p a i r >Ceci e s t l a case &nbsp ; 3</td> 34 <td class= impair >Ceci e s t l a case &nbsp ; 4</td> 35 </ tr> 36 <tr> 37 <td class= p a i r >Ceci e s t l a case&nbsp ; 5</td> 38 <td class= impair >Ceci e s t l a case &nbsp ; 6</td> 39 <td class= p a i r >Ceci e s t l a case &nbsp ; 7</td> 40 <td class= impair >Ceci e s t l a case &nbsp ; 8</td> 41 </ tr> 42 <tr> 43 <td class= p a i r >Ceci e s t l a case&nbsp ; 9</td> 44 <td class= impair >Ceci e s t l a case &nbsp ;10</td> 45 <td class= p a i r >Ceci e s t l a case &nbsp ;11</td> 45

47 Rémy Malgouyres, Programmation Web 46 <td class= impair >Ceci e s t l a case &nbsp ;12</td> 47 </ tr> 48 </tbody> 49 </ table> 50 </ div> 51 </body> 52 <! f i n du corps HTML > 53 </html> 54 <! f i n du code HTML > exemples/chapitrecss/ex08_classes_css_tableaux.css t a b l e { 4 padding : 0px ; 5 v e r t i c a l a l i g n : top ; /* mise en forme des t a b l e s */ 6 background c o l o r : #ddd ; 7 border s t y l e : o u t s e t ; 8 border width : 10px ; 9 border c o l o r : black ; 10 text a l i g n : c e n t e r ; 11 margin : 0 auto ; 12 } tr, td { 15 border s t y l e : dashed ; /* mise en forme des c e l l u l e s */ 16 border width : 2px ; 17 border c o l o r : black ; 18 padding : 20px ; 19 } tr, td. p a i r { 22 background c o l o r : black ; 23 c o l o r : white ; 24 } tr, td. impair { 27 background c o l o r : white ; 28 c o l o r : black ; 29 } th { 33 border s t y l e : s o l i d ; 34 border width : 2px ; 35 border c o l o r : black ; 36 text a l i g n :center ; 37 font weight : bolder ; 38 background c o l o r : #ddd ; 39 c o l o r : black ; 40 padding : 20px ; 41 } th. p a i r { 44 background c o l o r : #ccc ; 46

48 Chapitre 2 : Styles CSS et mise en page 45 } th. impair { 48 background c o l o r : #555 ; 49 } 50 caption { 51 background c o l o r : black ; 52 c o l o r : white ; 53 box shadow : 10 px 20 px 10 px #666 ; 54 width : 50% ; 55 margin : 0 auto 20px auto ; 56 } 2.6 Sélecteurs de style CSS par ID exemples/chapitrecss/ex09_id_selector_css.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta http equiv= Content Type content= t e x t /html ; c h a r s e t=utf 8 /> 5 <link rel= s t y l e s h e e t type= t e x t / c s s href=. / ex09_id_selector_css. c s s /> 6 <t i t l e>s é l e c t e u r s de s t y l e par ID</ t i t l e> 7 </head> 8 <body> 9 <h1>s é l e c t e u r s de s t y l e par ID</h1> 10 <h2 id= p a r t i e 1 >1) Qu est ce qu un <i>id</ i> <i>html</ i>&nbsp ;?</h2> 11 <p id= paragraphe1 > 12 Un développeur web peut a s s o c i e r un <i>id</ i> à tout élément <i>html</ i>. 47

49 Rémy Malgouyres, Programmation Web 13 Cet <i>id</ i> s o i t ê t r e unique dans tout l e document et c a r a c t é r i s e l élément. 14 Pour ce f a i r e, l e développeur web u t i l i s e l a t t r i b u t <code>id</code> de l a b a l i s e 15 qui d é f i n i t l élément. 16 </p> 17 <h2 id= p a r t i e 2 >2) À quoi s e r v e n t l e s <i>id</ i> <i>html</ i>&nbsp ;?</h2> 18 <p id= paragraphe2 > 19 L <i>id</ i> d un élément <i>html</ i> permet de d é s i g n e r l élément parmis 20 tous l e s éléments du document, notamment pour&nbsp ; : 21 <ul> 22 < l i> 23 Accéder à l élément pour a g i r sur son contenu en <i>j a v a s c r i p t</ i> 24 ( par exemple v i a l a méthode <code>getelementbyid</code>). 25 </ l i> 26 < l i> 27 I d e n t i f i e r l élément pour l u i a t t r i b u e r un s t y l e <i>css p a r t i c u l i e r</ i > 28 </ l i> 29 </ ul> 30 </p> 31 <h2 id= p a r t i e 3 >3) D i f f é r e n c e avec l e s c l a s s e s</h2> 32 <p id= paragraphe3 > 33 Contrairement aux c l a s s e s, 34 pour l e s q u e l l e s on peut d é f i n i r autant d éléments qu on veut dans une 35 même c l a s s e de s t y l e, <strong>l élément correspondant à un ID e s t unique</ strong>, 36 c e s t un <em>s i n g l e t o n</em>. 37 </p> 38 </body> 39 </html> 1 2 /* s t y l e par défaut du t e x t e */ 3 body { 4 font family : Comic Sans MS ; 5 font s i z e : 18 pt ; 6 background c o l o r : #f f f ; 7 c o l o r : #222 ; 8 } 9 10 /* s t y l e du t i t r e */ 11 h1 { 12 font weight : bold ; 13 font s i z e : 150% ; 14 c o l o r : white ; 15 text a l i g n : c e n t e r ; 16 background c o l o r : #999 ; 17 padding : 15 pt ; 18 } h2 { 21 font weight : bold ; 22 font s i z e : 120% ; exemples/chapitrecss/ex09_id_selector_css.css 48

50 Chapitre 2 : Styles CSS et mise en page 23 } h2#p a r t i e 1 { 26 c o l o r : black ; 27 } h2#p a r t i e 2 { 30 c o l o r : red ; 31 } h2#p a r t i e 3 { 34 c o l o r : green ; 35 } /* s t y l e des éléments importants */ 38 strong { 39 font v a r i a n t : small caps ; 40 font weight : bolder ; 41 c o l o r : black ; 42 } /* s t y l e des éléments mis en évidence */ 46 em { 47 font s t y l e : i t a l i c ; 48 c o l o r : black ; 49 } p { 52 background c o l o r : #ddd ; 53 text a l i g n : j u s t i f y ; 54 padding : 5 pt ; 55 } p#pa rag rap he1 { 58 background c o l o r : #aaa ; } p#pa rag rap he2 { 63 background c o l o r : #ccc ; } p#pa rag rap he3 { 68 background c o l o r : #eee ; } /* p#pa rag rap he2 { 73 background c o l o r : #ddd ; s t y l e par défaut des l i e n s */ 76 a { 77 c o l o r : blue ; 78 text d e c o r a t i o n : u n d e r l i n e ; /* non s o u l i g n é */ 49

51 Rémy Malgouyres, Programmation Web 79 } 50

52 Chapitre 2 : Styles CSS et mise en page La position des différents éléments dans une page HTML se définit au niveau du style CSS. 2.7 Marges et bordures Chaque élément (de type inline ou block) se trouve dans une boîte ayant une bordure, une marge intérieure, et une marge extérieure. On définit ainsi les épaisseurs et styles de bordure des différents éléments, les marges extérieures (margin), qui force l élément à un certain éloignement des autres éléments de la page, les marges intérieures (padding), qui force le contenu de l élément à se trouver à une certaine distance du bord de l élément. Voir la figure 2.2 Élément parent margin-top padding margin-left contenu de l élément margin-right Autre élément Bord de l élément considéré Figure 2.2 : Propriétés CSS margin et padding exemples/chapitrecss/ex10_margin_padding.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <style> 7 div { 8 border width : 2px ; 9 border c o l o r : black ; 10 border s t y l e : s o l i d ; 11 c o l o r : black ; 12 margin : 40px ; 13 padding : 25px ; 51

53 Rémy Malgouyres, Programmation Web 14 background c o l o r : #ddd ; 15 } div div { 18 border width : 3px ; 19 border c o l o r : #666 ; 20 border s t y l e : dashed ; 21 c o l o r : black ; 22 margin : 10px ; 23 padding : 35px ; 24 background c o l o r : #aaa ; 25 } 26 </ style> 27 <t i t l e>p r o p r i é t é s Margin et Padding</ t i t l e> 28 </head> 29 <body> 30 <h1>p r o p r i é t é s Margin et Padding</h1> 31 <div> 32 Ceci e s t l e t e x t e f a i s a n t p a r t i e du contenu de l a première b o î t e. 33 <div> 34 Ceci e s t l e texte, contenu de l a p e t i t e b o î t e. 35 Cette p e t i t e b o î t e e s t e l l e même l e contenu de l a grande b o î t e. 36 </ div> 37 </ div> 38 </body> 39 </html> 2.8 Positionnement absolu Dans le positionnement absolu, la position d un élément est définie par rapport à la position du première ancêtre positionné (soit le parent si celui-ci est positionné, sinon on cherche le parent du parent, etc. jusqu à trouver un ancêtre positionné). Si le parent n est pas positionné, on peut le positionner sans changer sa position en mettant sa position relative zéro. Voir la figure 2.3. Un élément positionné en absolu est sorti du flux : il n occupe plus de place dans le flux et l élément suivant est placé comme si l élément positionné en absolu n existait pas. L élément positionné en absolu n occupe pas de place. Premier ancètre positionné Décalage bord top Décalage bord left Figure 2.3 : Positionnement Absolu d un élément 52

54 Chapitre 2 : Styles CSS et mise en page exemples/chapitrecss/ex11_position_absolute.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <style> 7 div { 8 border width : 2px ; 9 border c o l o r : black ; 10 border s t y l e : s o l i d ; 11 c o l o r : black ; 12 margin : 20px ; 13 padding : 0px ; 14 background c o l o r : #ddd ; 15 } /* positionnement normale dans l e flux, 18 d é f i n i j u s t e pour p o s i t i o n n e r l élément */ 19. p o s i t i o n Z e r o { 20 p o s i t i o n : r e l a t i v e ; 21 top : 0px ; l e f t : 0px ; 24 width : 500px ; 25 z index : 1 ; 26 } div div { 29 border width : 2px ; 30 border c o l o r : black ; 31 border s t y l e : dashed ; 32 margin : 0px ; 33 padding : 0px ; 34 background c o l o r : #aaa ; 35 } p o s i t i o n T r e n t e { 38 p o s i t i o n : a b s o l u t e ; 39 top : 90px ; /* d é c a l a g e e n t r e l e bord haut de l élément et son a n c è t r e */ 53

55 Rémy Malgouyres, Programmation Web 40 l e f t : 30px ;/* d é c a l a g e e n t r e l e bord gauche de l élément et son a n c è t r e */ 41 width : 500px ; 42 z index : 7 ; 43 } p o s i t i o n S o i x a n t e { 46 p o s i t i o n : a b s o l u t e ; 47 top : 180px ; /* d é c a l a g e e n t r e l e bord haut de l élément et son a n c è t r e */ 48 l e f t : 60px ; /* d é c a l a g e e n t r e l e bord gauche de l élément et son a n c è t r e */ 49 background c o l o r : #888 ; 50 z index : 15 ; 51 } 52 </ style> 53 <t i t l e>positionnement absolu</ t i t l e> 54 </head> 55 <body> 56 <h1>positionnement absolu</h1> 57 <div class= p o s i t i o n Z e r o > 58 Ceci e s t l e t e x t e f a i s a n t p a r t i e du contenu de l a b o î t e parente. Celle c i e s t 59 p o s i t i o n n é e mais à sa p l a c e normale dans l e f l u x ( marge de 20px ). 60 <div class= p o s i t i o n T r e n t e > 61 Ceci e s t l e t e x t e contenu de l a première sous boîte, dont l e coin s u p é r i e u r 62 gauche p o s i t i o n n é e 30 p i x e l s à d r o i t e et 90 p i x e l s plus bas que son parent. 63 </ div> 64 <div class= p o s i t i o n S o i x a n t e > 65 Ceci e s t l e t e x t e contenu de l a deuxième sous boîte, dont l e coin s u p é r i e u r 66 gauche p o s i t i o n n é e 60 p i x e l s à d r o i t e et 180 p i x e l s plus bas que son parent. 67 </ div> 68 </ div> 69 </body> 70 </html> 2.9 Positionnement relatif Le positionnement relatif permet de déplacer un objet relativement à la position qu il aurait eu dans le flux sans positionnement. Le positionnement relatif s obtient avec l attribut : position : relative; top: 10px; /* déplacer de 10 pixels vers le bas */ left: 20px; /* déplacer de 20 pixels vers la droite */ 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> exemples/chapitrecss/ex12_position_relative.html 54

56 Chapitre 2 : Styles CSS et mise en page 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <style> 7 /* positionnement normale dans l e flux, 8 d é f i n i j u s t e pour p o s i t i o n n e r l élément */ 9. p o s i t i o n Z e r o { 10 p o s i t i o n : r e l a t i v e ; 11 width : 600px ; 12 z index : 1 ; 13 } 14. p o s i t i o n T r e n t e { 15 border s t y l e : dashed ; 16 background c o l o r : #aaa ; 17 p o s i t i o n : r e l a t i v e ; 18 l e f t : 60px ; 19 width : 600px ; 20 z index : 7 ; 21 } 22. positionnormale { 23 border s t y l e : dashed ; 24 background c o l o r : #888 ; 25 z index : 15 ; 26 } 27 </ style> 28 <t i t l e>positionnement r e l a t i f</ t i t l e> 29 </head> 30 <body> 31 <h1>positionnement r e l a t i f</h1> 32 <div class= p o s i t i o n Z e r o > 33 Ceci e s t l e t e x t e f a i s a n t p a r t i e du contenu de l a b o î t e du haut. Celle c i e s t 34 p o s i t i o n n é e mais à sa p l a c e normale dans l e f l u x. 35 </ div> 36 <div class= p o s i t i o n T r e n t e > 37 Ceci e s t l e t e x t e contenu de l a b o î t e du milieu, dont l e c oin s u p é r i e u r 38 gauche p o s i t i o n n é e 60 p i x e l s à d r o i t e de sa p o s i t i o n normale dans l e f l u x. 39 </ div> <div class= positionnormale > 42 Ceci e s t l e t e x t e contenu de l a b o î t e du bas, qui e s t p o s i t i o n n é e 43 normalement dans l e f l u x ( compte tenu de l a p o s i t i o n de l a b o î t e précédente ). 44 </ div> 45 </body> 55

57 Rémy Malgouyres, Programmation Web 46 </html> 2.10 Structuration d une page en HTML5 La mise en page avec header, navigation et pied de page est si courante que des balises spécialisées, appelées balises sémantiques ont été créées en HTML5. On doit les préférer à <div> car elles permettent une plus grande clarté de la structure du document, mais aussi aux moteurs de recherche de mieux percevoir quelle place accorder aux différentes parties d une page web. Les balises sémantiques sont les suivantes : header pour l en-tête ou le bandeau contenant le titre de la page, un logo, etc. footer pour le pied de pas contenant le copyright, des logos ou liens, informations légales, etc. nav pour la partie navigation avec un menu et des liens pour se déplacer dans le site. article contenant un corps de document autosuffisant. aside pour des informations annexes sans grand rapport avec le sujet (publicités, etc.) section représentant une partie regroupant plusieurs contenus liés entre eux. Voici un exemple de mise en page typique utilisant ces balises : 56

58 Chapitre 2 : Styles CSS et mise en page exemples/chapitrecss/ex13_balises_semantiques.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>b a l i s e s Sémantiques <i>html5</ i></ t i t l e> 7 </head> 8 <body> 9 <header> 10 <h1>b a l i s e s Sémantiques <i>html5</ i></h1> 11 </ header> 12 <div> 13 <nav> 14 <h1>navigation</h1> 15 <ul> 16 < l i> 17 <a href=. / coucou. html >l i e n 1</a> 18 </ l i> 19 < l i> 20 <a href=. / toto. html >l i e n 2</a> 21 </ l i> 22 < l i> 23 <a href=. / t i t i. html >l i e n 2</a> 24 </ l i> 25 </ ul> 26 </ nav> 27 <a r t i c l e> 28 <h1>les b a l i s e s &l t ; header&gt ;, &l t ; nav&gt ;, &l t ; a r t i c l e&gt ;, &l t ; f o o t e r &gt ;</h1> 29 <p> 30 Ces b a l i s e s d é f i n i s s e n t l a s t r u c t u r e g é n é r a l e du document. E l l e s se comportent 31 comme un &l t ; div&gt ; mais e l l e s ont, comme l e u r nom l indique, une s i g n i f i c a t i o n 32 au niveau sémantique&nbsp ; : 33 </p> 34 <o l> 35 < l i> 36 Un élément &l t ; header&gt ; c o n t i e n t l en t ê t e du document avec l e nom g é n é r a l 37 du s i t e, un logo, une banière, éventuellement un slogan, e t c. 38 </ l i> 39 < l i> 40 Un élément &l t ; nav&gt ; c o n t i e n t des éléments de n a v i g a t i o n ( menus, s é r i e s de l i e n s, e t c. ). 41 Les moteurs de r e c h e r c h e peuvent en déduite un <em>sitemap</em>, c e s t à d i r e l a s t r u c t u r e du s i t e 42 pour o p t i m i s e r l e référencement. 43 </ l i> 44 < l i> 45 Un élément &l t ; a r t i c l e&gt ; c o n t i e n t l e contenu de l a page l u i même. C e s t l e t e x t e de l a r t i c l e 46 qui s e r a p r i s en compte fortement pour l i n d e x a t i o n dans l e s moteurs de r e c h e r c h e. 47 </ l i> 57

59 Rémy Malgouyres, Programmation Web 48 < l i> 49 Un élément &l t ; f o o t e r&gt ; c o n t i e n t un pied de page ( souvent avec des i n f o r m a t i o n s l é g a l e s, de copyright, 50 sur l e c r é a t e u r technique du s i t e, l e s l o g o s des sponsors, e t c. ) 51 </ l i> 52 </ ol> 53 <p> 54 Les moteurs de r e c h e r c h e peuvent a i n s i mieux a n a l y s e r l e contenu de l a page&nbsp ; c e l à p a r t i c i p e 55 de l o p t i m i s a t i o n du référencement ; 56 </p> 57 </ a r t i c l e> 58 <f o o t e r> 59 &copy ; RM </ f o o t e r> 61 </ div> 62 </body> 63 </html> 2.11 Exemples de mise en page exemples/chapitrecss/ex14_exemple_miseenpage.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / ex14_exemple_miseenpage. c s s /> 6 <t i t l e>exemple de mise en page</ t i t l e> 7 </head> 8 <body> 9 <header> 10 <h1>exemple de mise en page</h1> 11 </ header> 12 <div> 13 <nav> 14 <h1>navigation</h1> 15 <ul> 16 < l i> 58

60 Chapitre 2 : Styles CSS et mise en page 17 <a href=. / coucou. html >l i e n 1</a> 18 </ l i> 19 < l i> 20 <a href=. / toto. html >l i e n 2</a> 21 </ l i> 22 < l i> 23 <a href=. / t i t i. html >l i e n 2</a> 24 </ l i> 25 </ ul> 26 </ nav> 27 <a r t i c l e> 28 <h1>corps du t e x t e</h1> 29 <p> 30 Nous mettons i c i l e corps du t e x t e. Paragraphe </p> 32 <p> 33 Notons que l e s l i e n s dans l e menu n ont pas l e même aspect 34 que l e s l i e n s dans l e t e x t e. Le s t y l e e s t propre à chaque 35 zône de l a page. 36 </p> 37 <p> 38 Ceci e s t <a href=. / toto. html >un l i e n</a> normal 39 </p> 40 </ a r t i c l e> 41 </ div> 42 <f o o t e r> 43 &copy ; RM </ f o o t e r> 45 </body> 46 </html> exemples/chapitrecss/ex14_exemple_miseenpage.css 1 /*****************************************************\ 2 * STYLE CSS POUR MISE EN PAGE EN LARGEUR FIXE 3 * MENU À GAUCHE 4 * ***************************************************/ 5 6 /* L ensemble du document */ 7 body { 8 font family : times, s e r i f ; /* p o l i c e */ 9 font s i z e : 14 pt ; /* t a i l l e de f o n t e absolue */ 10 background c o l o r : #ccc ; /* c o u l e u r de fond de l a page */ 11 c o l o r : #222 ; /* c o u l e u r de t e x t e g r i s f o n c é */ 12 } /* l i e n s par défaut */ 15 a{ 16 /* s t y l e par défaut pour é v i t e r que ne s o i t p r i s par défaut * 17 * l e s t y l e du div nav ul l i a d é f i n i plus bas */ 18 } /* Le header : b a n i è r e de t i t r e du s i t e */ 21 header { 22 width : 600px ; /* l a r g e u r t o t a l e du contenu */ 23 background c o l o r : black ; /* fond du header n o i r */ 59

61 Rémy Malgouyres, Programmation Web 24 c o l o r : white ; /* c o u l e u r du t e x t e : blanc */ 25 margin : 0 auto ; /* l e header e s t c e n t r é dans l a page */ 26 padding : 0px ; /* pas de padding */ 27 } /* t i t r e p r i n c i p a l du s i t e dans l e header */ 30 header h1 { 31 text a l i g n : c e n t e r ; /* t e x t e c e n t r é dans l e h1 ( l u i même c e n t r é dans l e header ) */ 32 width : i n h e r i t ; /* prend toute l a l a r g e u r du parent */ 33 margin : 0 ; /* pas d espace autour du header et de son t i t r e */ 34 } /* sous l e header, l e div c o n t i e n t l e nav et l a r t i c l e */ 37 div { 38 width : 600px ; /* l a r g e u r du contenu : 600px ; */ 39 background c o l o r : white ; /* fond blanc */ 40 margin : 0 auto ; /* c e n t r é dans l a page */ 41 p o s i t i o n : r e l a t i v e ; /* positionnement pour pouvoir u t i l i s e r p o s i t i o n : a b s o l u t e dans l e s f i l s */ 42 top : 0px ; 43 padding : 0px ; /* pas de marge i n t é r i e u r e */ 44 height : 280px ; /* hauteur t o t a l du contenu */ 45 } /* bloc de n a v i g a t i o n contenant l e menu */ 48 nav { 49 c o l o r : white ; /* t e x t e blanc */ 50 text a l i g n : c e n t e r ; /* t e x t e c e n t r é */ 51 background c o l o r : #999 ; /* fond g r i s */ 52 width : 180px ; /* l a r g e u r : seulement une p a r t i e des 600px */ 53 margin : 0 ; /* pas de marge e x t é r i e u r e */ 54 padding : 0px ; /* pas de marge i n t é r i e u r e */ 55 p o s i t i o n :absolute ; /* on c a l e l e b loc à gauche sur l e bord du div parent */ 56 l e f t :0px ; 57 height : i n h e r i t ; /* l a hauteur e s t l a même que l a hauteur du div parent */ 58 } /* t i t r e du menu */ 61 nav h1{ 62 background c o l o r : black ; /* fond n o i r */ 63 border r a d i u s : 4px ; /* bord légèrement a r r o n d i */ 64 width : 80% ; /* l a r g e u r 80% de l a l a r g e u r du nav */ 65 margin : 20px auto ; /* cantré en h o r i z o n t a l et 20px de marge au dessus et au dessous */ 66 } /* L i s t e à puce contenant l e s l i e n s du menu */ 69 div nav ul { 70 text a l i g n : l e f t ; /* t e x t e c a l é à gauche */ 71 l i s t s t y l e : none ; /* pas de p o i n t s devant l e s items de l a l i s t e à puces */ 72 } /* items de l a l i s t e à puce contenant l e s l i e n s du menu */ 75 div nav ul l i { 76 margin bottom : 20px ; /* permet d é c a r t e r l e s boutons */ 60

62 Chapitre 2 : Styles CSS et mise en page 77 } /* l i e n s du menu dans l a p a r t i e n a v i g a t i o n */ 80 div nav ul l i a { 81 text d e c o r a t i o n : none ; /* pas de soulignement du l i e n */ 82 font v a r i a n t : small caps ; /* p e t i t e s c a p i t a l e s */ 83 c o l o r : white ; /* t e x t e blanc */ 84 font weight : bolder ; /* c a r a c t è r e s gras */ 85 background image : l i n e a r g r a d i e n t ( black, white ) ; /* fond dégradé */ 86 border r a d i u s : 4px ; /* bord légèrement a r r o n d i */ 87 padding : 10px ; /* marge i n t é r i e u r e au bouton */ 88 } /* p a r t i e a r t i c l e contenant l e t e x t e p r i n c i p a l l e l a page */ 91 div a r t i c l e { 92 c o l o r : black ; /* t e x t e n o i r ( sur fond blanc ) */ 93 width : 400 px ; /* encombrement 420 avec l a padding. 600 px = 180 px px */ 94 padding : 0 10px ; /* compter 20 dans l a l a r g e u r t o t a l e */ 95 margin : 0 ; /* pas de marge e x t é r i e u r e */ 96 p o s i t i o n : r e l a t i v e ; 97 l e f t : 180px ; /* on d é c a l e v e r s l a d r o i t e de l a l a r g e u r du nav */ 98 height : i n h e r i t ; /* prend l a hauteur de son parent */ 99 } /* T i t r e p r i n c i p a l de l a page dans l a r t i c l e */ 102 div a r t i c l e h1{ 103 margin : 0 auto ; /* t i t r e c e n t r é dans l a r t i c l e */ 104 text a l i g n : c e n t e r ; /* t e x t e c e n t r é dans l e t i t r e */ 105 } /* paragraphes de l a r t i c l e */ 108 div a r t i c l e p { 109 text a l i g n : j u s t i f y ; /* t e x t e j u s t i f i é dans l e s paragraphes */ 110 } /* pied de page */ 113 f o o t e r { 114 width : 600px ; /* l a r g e u r 600 p i x e l s */ 115 margin : 0 auto ; /* f o o t e r c e n t r é dans l a page */ 116 background c o l o r : black ; /* fond n o i r */ 117 c o l o r : white ; /* t e x t e blanc */ 118 text a l i g n : c e n t e r ; /* t e x t e c e n t r é */ 119 } La structure du document HTML5 est définie par ces balises, mais pas la disposition de la page. En changeant uniquement le CSS, on peut obtenir : exemples/chapitrecss/ex15_miseenpage_2.css 1 /**************************************************************\ 2 * STYLE CSS POUR MISE EN PAGE EN LARGEUR PROPORTIONNELLE 3 * (LA LARGEUR S ADAPTE À LA PAGE. MENU EN HAUT SOUS LE HEADER 4 * ************************************************************/ 5 6 /* L ensemble du document */ 7 body { 8 font family : times, s e r i f ; /* p o l i c e */ 61

63 Rémy Malgouyres, Programmation Web 9 font s i z e : 14 pt ; /* t a i l l e de f o n t e absolue */ 10 background c o l o r : #ccc ; /* c o u l e u r de fond de l a page */ 11 c o l o r : #222 ; /* c o u l e u r de t e x t e g r i s f o n c é */ 12 } /* Tous l e s div */ 15 div { 16 background c o l o r : #f f f ; /* fond blanc */ 17 } /* Le header : b a n i è r e de t i t r e du s i t e */ 20 header { 21 width : 60% ; /* l a r g e u r 60% de l a page */ 22 background c o l o r : black ; /* fond n o i r */ 23 c o l o r : white ; /* t e x t e blanc */ 24 margin : 0 auto ; /* l e header e s t c e n t r é dans l a page */ 25 border r a d i u s : 20px 20px 0 0 ; /* a n g l e s du haut a r r o n d i s */ 26 } /* t i t r e p r i n c i p a l du s i t e dans l e header */ 29 header h1 { 30 text a l i g n : c e n t e r ; /* t e x t e c e n t r é dans l élément */ 31 width : 100% ; /* occupe toute l a l a r g e u r du parent ( c. a. d. du header ) */ 32 margin : 0 ; /* pas de marge c o l l é au contenu div. content */ 33 } /* div contenant l a r t i c l e et l e nav */ 36 div { 37 width : 60% ; /* l a r g e u r 60% de l a page */ 38 background c o l o r : white ; /* fond blanc */ 39 margin : 0 auto ; /* contenu c e n t r é dans l a page */ 40 } /* mise en forme de l a p a r t i e n a v i g a t i o n contenant l e menu */ 43 div nav { 44 text a l i g n : c e n t e r ; /* t e x t e c e n t r é */ 45 background c o l o r : #999 ; /* fond g r i s f o n c é */ 46 width : 100% ; /* l a r g e u r 100% du div parent */ 47 height : 45px ; /* hauteur absolue 45px */ 48 } /* t i t r e du menu */ 62

64 Chapitre 2 : Styles CSS et mise en page 51 div nav h1{ 52 d i s p l a y : none ; /* on supprime l e t i t r e */ 53 } /* L i s t e à puce contenant l e s l i e n s du menu */ 56 div nav ul { 57 l i s t s t y l e : none ; /* on supprime l e s p o i n t s devant l e s items de l a l i s t e à puces */ 58 margin top : 0 ; /* bord du haut a l i g n é sur l e bord du div parent */ 59 } /* items de l a l i s t e à puce contenant l e s l i e n s du menu */ 62 div nav ul l i { 63 d i s p l a y : i n l i n e block ; /* l e s items sont rangés horizontalement au l i e u de v e r t i c a l e m e n t */ 64 } /* l i e n s du menu dans l a p a r t i e n a v i g a t i o n : *\ 67 \* p r o p r i é t é s g é n é r a l e s communes aux l i e n s v i s i t é s, hover ou non */ 68 div nav ul l i a { 69 font weight : bolder ; /* c a r a c t è r e s gras */ 70 border s t y l e : none ; /* pas de bord */ 71 margin : 0 10px ; /* marges à d r o i t e et à gauche de chaque l i e n de menu */ 72 padding : 5px 10px ; /* espace autour du t e x t e */ 73 p o s i t i o n : r e l a t i v e ; /* on t r a n s l a t e l élément */ 74 top : 5px ; /* d é c a l a g e v e r s l e bas pour compenser l e padding et a l i g n e r l e bord haut */ 75 border r a d i u s : px 10px ; /* a n g l e s du bas a r r o n d i s */ 76 text d e c o r a t i o n : none ; /* t e x t e non s o u l i g n é */ 77 } /* p r o p r i é t é s s p é c i f i q u e s des l i e n s non v i s i t é s non s u r v o l é s */ 80 div nav ul l i a : l i n k { 81 c o l o r : white ; /* t e x t e blanc */ 82 background c o l o r : black ; /* fond n o i r */ 83 } /* p r o p r i é t é s s p é c i f i q u e s des l i e n s v i s i t é s non s u r v o l é s */ 86 div nav ul l i a : v i s i t e d { 87 c o l o r : #444 ; /* g r i s foncé */ 88 background c o l o r : #ddd ; /* g r i s c l a i r */ 89 } /* p r o p r i é t é s s p é c i f i q u e s des l i e n s s u r v o l é s */ 92 div nav ul l i a :hover { 93 c o l o r : black ; /* t e x t e n o i r */ 94 background c o l o r : white ; /* fond blanc */ 95 } /* p a r t i e a r t i c l e contenant l e t e x t e p r i n c i p a l l e l a page */ 98 div a r t i c l e { 99 c o l o r : black ; /* c o u l e u r n o i r e */ 100 background c o l o r : white ; /* fond blanc */ 101 } /* T i t r e p r i n c i p a l de l a page dans l a r t i c l e */ 63

65 Rémy Malgouyres, Programmation Web 104 div a r t i c l e h1 { 105 text a l i g n : c e n t e r ; /* t e x t e c e n t r é ( dans l a r t i c l e ) */ 106 padding : 10px ; /* un peu d espace autour du t e x t e */ 107 margin : 0 ; /* pas de marge : bords a l i g n é s */ 108 background image : l i n e a r g r a d i e n t (#999, white ) ; /* dégradé de c o u l e u r s */ 109 } /* paragraphes de l a r t i c l e */ 112 div a r t i c l e p { 113 text a l i g n : j u s t i f y ; /* t e x t e j u s t i f i é */ 114 padding : 5px 10px ; /* un peu d espace autou des paragraphes */ 115 } /* pied de page */ 118 f o o t e r { 119 width : 60% ; /* l a r g e u r 60% de l a page */ 120 background c o l o r : #444 ; /* fond g r i s f o n c é */ 121 c o l o r : white ; /* t e x t e blanc */ 122 margin : 20px auto ; /* a l i g n é sur l a bas de l a r t i c l e */ 123 text a l i g n : c e n t e r ; /* t e x t e c e n t r é dans l e pied de page */ 124 border r a d i u s : px 20px ; /* a n g l e s du bas */ 125 } 2.12 CSS adaptatifs : Media Queries Les Media Queries permettent de créer des styles différents selon l écran sur lequel la page s affiche. Par exemple, on peut mettre deux feuilles de style différentes selon la mise taille de l écran. L exemple suivant, qui s appuie sur les deux exemples de mise en page précédents, crée une mise en page différente pour les largeur d affichage inférieur ou supérieure à 1000px. On met le menu à gauche pour les écrans suffisamment larges, et un menu en haut pour les écrans un peu étroit. exemples/chapitrecss/ex16_mediaqueries.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <! MISE EN PAGE PAR DÉFAUT : menu à gauche > 6 <link rel= s t y l e s h e e t media= ( min width : 1001px ) href=. / ex14_exemple_miseenpage. c s s /> 7 <! MISE EN PAGE POUR PETITS ÉCRANS : menu en haut > 8 <link rel= s t y l e s h e e t media= (max width : 1000px ) href=. / ex15_miseenpage_2. c s s /> 9 <t i t l e>exemple de mise en page</ t i t l e> 10 </head> 11 <body> 12 <header> 13 <h1>exemple de mise en page</h1> 14 </ header> 15 <div class= content > 16 <nav> 17 <h1>navigation</h1> 18 <ul> 64

66 Chapitre 2 : Styles CSS et mise en page 19 < l i> 20 <a href=. / coucou. html >l i e n 1</a> 21 </ l i> 22 < l i> 23 <a href=. / toto. html >l i e n 2</a> 24 </ l i> 25 < l i> 26 <a href=. / t i t i. html >l i e n 2</a> 27 </ l i> 28 </ ul> 29 </ nav> 30 <a r t i c l e> 31 <h1>corps du t e x t e</h1> 32 <p> 33 Nous mettons i c i l e corps du t e x t e. Paragraphe </p> 35 <p> 36 Notons que l e s l i e n s dans l e menu n ont pas l e même aspect 37 que l e s l i e n s dans l e t e x t e. Le s t y l e e s t propre à chaque 38 zône de l a page. 39 </p> 40 <p> 41 Ceci e s t <a href=. / toto. html >un l i e n</a> normal 42 </p> 43 </ a r t i c l e> 44 </ div> 45 <f o o t e r> 46 &copy ; RM </ f o o t e r> 48 </body> 49 </html> Notons qu on peut aussi créer des styles différents selon l écran balise par balise au cas par cas, comme dans l exemple de code suivant : ( min width : 400 px ) and ( max width : 500 px ) { 2 t a b l e tbody t r td { 3 padding 10 px ; 4 } 5 } 6 ( min width : 501px ) { 8 t a b l e tbody t r td { 9 padding 20 px ; 10 } 11 } Ou peut aussi prendre en compte le changement d orientation de l affichage d un mobile en portrait ou paysage : 1 <! MISE EN PAGE POUR L ORIENTATION PAYSAGE : menu à gauche > 2 <link rel= s t y l e s h e e t media= ( o r i e n t a t i o n :landscape ) href=. / ex14_exemple_miseenpage. c s s /> 3 <! MISE EN PAGE POUR POUR L ORIENTATION PORTRAIT : menu en h a u t > 65

67 Rémy Malgouyres, Programmation Web 4 <link rel= s t y l e s h e e t media= ( o r i e n t a t i o n : p o r t r a i t ) href=. / ex15_miseenpage_2. c s s /> 66

68 Deuxième partie Bases du langage PHP 67

69 68

70 Table of Contents 3 PHP procédural Notion de CGI Générer du code HTML avec un CGI en PHP Exemple de fonction en PHP Inclure un fichier PHP dans un autre Arithmétique : types int et float Tableaux indexés : avec une clé de type int Tableaux associatifs : avec une clé de type String Passage de paramètre à un script PHP Variables Locales ou Globales, Références Les classes en PHP Exemples de classes PHP Classes de Base Structuration des Objets, Vues Utilisation des Classes et Vue HTML Validation en entrée et gestion d une exception Qu est-ce que le filtrage? Le Package People\Individuals Classe Personne avec filtrage dans les setters Test de construction de Personnes et récupération des exceptions Classe Employe héritant de la classe Personne

71 70 TABLE OF CONTENTS

72 Chapitre 3 PHP procédural 3.1 Notion de CGI On appelle Common Gateway Interface, ou en abrégé CGI, une interface, utilisée par les serveurs HTTP, qui permet de générer la réponse du serveur par un programme, qui s exécute sur le serveur. Le programme pourra, assez typiquement, générer du code HTML qui sera affiché par un navigateur côté client. L interface CGI est indépendante du langage de programmation utilisée par le serveur, et n utilise que les flux standards et les variables d environnement. Voici un exemple de CGI programmé en C : 1 #i n c l u d e <s t d i o. h> 2 3 extern char ** environ ; 4 5 i n t main ( void ) exemples/cgi-bin/environ.c 71

73 Rémy Malgouyres, Programmation Web 6 { 7 i n t i ; 8 p r i n t f ( %s%c%c \n, Content Type :text /html ; c h a r s e t=i s o , 1 3, 1 0 ) ; 9 10 p r i n t f ( <html> ) ; 11 p r i n t f ( <head> ) ; 12 p r i n t f ( <t i t l e >Exemple de CGI</ t i t l e > ) ; 13 p r i n t f ( </head> ) ; 14 p r i n t f ( <body> ) ; 15 p r i n t f ( <h1>v a r i a b l e s d Environnement d un <i >CGI</i ></h1> ) ; f o r ( i =0 ; environ [ i ]!=NULL ; i ++){ 18 p r i n t f ( %s<br/>\n, environ [ i ] ) ; 19 } p r i n t f ( </body> ) ; 22 p r i n t f ( </html> ) ; 23 return 0 ; 24 } 3.2 Générer du code HTML avec un CGI en PHP Le PHP est un langage de programmation (ou langage de scripts) qui permet de générer et d afficher des pages webs dynamiques, c est à dire des pages dont le contenu dépend des actions de l utilisateur ou de l état, par exemple, d une base de données. En fin de compte, le code affiché est toujours du code HTML. Ce code HTML est généré par le programme PHP via la commande echo. La protection des caractères spéciaux du HTML (comme les guillemets) et le mélange du code PHP et du code HTML rend souvent le code d un script PHP. Nous verrons plus loin comment atténuer ce problème par une approche modulaire fondée sur la programmation objet. Le script PHP est inséré à l intérieur d une balise <?php > qui peut s insérer au sein du code HTML. exemples/php1/ex01_helloworld.php 72

74 Chapitre 3 : PHP procédural 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= utf 8 /> 5 <t i t l e>hello World en PHP</ t i t l e> 6 </head> 7 <body> 8 <p> 9 <?php // début du script PHP 10 echo Hello World! ; 11 // On a f f i c h e du code HTML s i l a s o r t i e 12?> <! f i n du script PHP > 13 </p> 14 </body> 15 </html> 3.3 Exemple de fonction en PHP Ici, nous voyons une fonction PHP qui génère l en-tête XHTML du document et son header. Cette fonction prend en paramètre le titre, le charset et l url d une feuille de style CSS à appliquer dans le header HTML. Le résultat est que lors de l utilisation de la fonction, presque tout le code HTML disparait pour être remplacé par une seule ligne de code, ce qui en fin de compte allégera de beaucoup le code source PHP. exemples/php1/ex02_function.php 1 <?php // début d un script PHP 2 f u n c t i o n outputentetehtml5 ( $ t i t l e, $charset, $css_sheet ) { 3 // s o r t i e du doctype. Les g u i l l e m e t s HTML sont p r o t é g é s par \ 4 echo <!doctype html>\n ; 5 echo <html lang=\ f r \ >\n ; 6 echo <head>\n ; 7 echo <meta c h a r s e t=\ ; 8 echo $ c h a r s e t ; 9 echo \ />\n ; 73

75 Rémy Malgouyres, Programmation Web 10 echo <l i n k r e l =\ s t y l e s h e e t \ h r e f=\ ; 11 echo $css_sheet ; 12 echo \ />\n ; 13 // concaténation de c h a î n e s de c a r a c t è r e s. 14 echo <t i t l e >. $ t i t l e. </ t i t l e >\n ; 15 echo </head>\n<body>\n ; 16 } 17?> 18 <?php 19 f u n c t i o n outputfinfichierhtml5 ( ) 20 { 21 echo </body>\n</html>\n ; 22 } 23?> <?php 26 outputentetehtml5 ( Hello world v e r s i o n 2, UTF 8, mystyle. css ) ; 27?> 28 <?php // début du script PHP 29 echo <p>hello World!</p> ; // On a f f i c h e du code HTML s i l a s o r t i e 30 // f i n du script PHP 31?> 32 <?php 33 outputfinfichierhtml5 ( ) ; 34?> 3.4 Inclure un fichier PHP dans un autre Évidemment, si le but des fonctions PHP est de cacher et de réutiliser une partie du code, il est commode de pouvoir écrire une fois pour toutes la fonction dans un seul fichier, puis d utiliser la fonction dans tous nos scripts par la suite. Ici les fonctions outputentetexhtml et outputfinfichierxhtml sont utilisées dans tous les scripts qui affichent du code HTML. (en effet, nous verrons plus loin que certains fichiers PHP sont de la pure programmation et n affichent rien.) exemples/php1/commonfunctions.php 1 <?php // début d un script PHP 2 f u n c t i o n outputentetehtml5 ( $ t i t l e, $charset, $css_sheet ) { 3 // s o r t i e du doctype. Les g u i l l e m e t s HTML sont p r o t é g é s par \ 4 echo <!doctype html>\n ; 5 echo <html lang=\ f r \ >\n ; 6 echo <head>\n ; 7 echo <meta c h a r s e t=\ ; 8 echo $ c h a r s e t ; 9 echo \ />\n ; 10 echo <l i n k r e l =\ s t y l e s h e e t \ h r e f=\ ; 11 echo $css_sheet ; 12 echo \ />\n ; 13 // concaténation de c h a î n e s de c a r a c t è r e s. 14 echo <t i t l e >. $ t i t l e. </ t i t l e >\n ; 15 echo </head>\n<body>\n ; 16 } 17?> 74

76 Chapitre 3 : PHP procédural <?php 20 f u n c t i o n outputfinfichierhtml5 ( ) 21 { 22 echo </body>\n</html>\n ; 23 } 24?> exemples/php1/ex03_include.php 1 <?php r e q u i r e (. / commonfunctions. php ) ; 2 3 outputentetehtml5 ( Hello world v e r s i o n 3, UTF 8, mystyle. css ) ; 4?> 5 <p> 6 <?php // début du script PHP 7 echo Hello World! ; // On a f f i c h e du code HTML s i l a s o r t i e 8 // f i n du script PHP 9?> 10 </p> 11 <?php 12 outputfinfichierhtml5 ( ) ; 13?> 3.5 Arithmétique : types int et float En PHP, on ne déclare pas les types des variables ou des paramètres de fonctions. Celui-ci est défini lors de l initialisation de la fonction. Des fonctions permettent cependant de tester le type ou d accéder au nom du type d une variable. Nous en verrons par la suite. exemples/php1/ex04_arithmetique_types.php 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 outputentetehtml5 ( Arithmétique f l o t t a n t e et e n t i è r e, UTF 8, mystyle. css ) ; 75

77 Rémy Malgouyres, Programmation Web 5?> 6 <p> 7 <?php // début du script PHP 8 f u n c t i o n appliquetva ( $prixht, $taux ) { 9 $prixttc = $prixht *(1.0+ $taux / ) ; 10 return $prixttc ; 11 } 12?> 13 <h1>calcul de TVA</h1> 14 <p> 15 <?php 16 $prix = ; 17 echo Pour un p r i x hors taxe de. $ prix. &euro ; et un taux de 19,6%\n ; 18 echo l e p r i x TTC e s t de : 19. round ( appliquetva ( $prix, ), 2 ). &euro ;. \ n ; 20 echo <br/>\ nallez! On a r r o n d i à :. i n t v a l ( appliquetva ( $prix, ) ). &euro ;. \ n ; 21?> 22 </p> 23 <?php 24 outputfinfichierhtml5 ( ) ; 25?> 3.6 Tableaux indexés : avec une clé de type int On crée un tableau avec la fonction array. On accéde à ses éléments (ici indexés par un int) en utilisant des crochets [ ]. La taille des tableaux peut être obtenue via la fonction sizeof. exemples/php1/ex05_tableaux_keyint.php 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 outputentetehtml5 ( Tableaux 1, UTF 8, mystyle. css ) ; 76

78 Chapitre 3 : PHP procédural 5?> 6 <p> 7 <h1>tableaux avec c l é e n t i è r e s</h1> 8 <p> 9 <?php 10 $tableau = array (23, 45, 41, 6, 04) ; 11 echo ( ; 12 for ( $ i=0 ; $ i < count ( $tableau ) ; $ i++) { 13 echo $tableau [ $ i ] ; 14 i f ( $ i + 1 < count ( $tableau ) ) 15 echo, ; 16 } 17 echo ) \n ; 18?> 19 </p> 20 <?php 21 outputfinfichierhtml5 ( ) ; 22?> 3.7 Tableaux associatifs : avec une clé de type String Il existe en PHP une deuxième sorte de tableaux : les tableaux associatifs, ainsi nommés car ils associent une valeur à une clef qui est une chaîne de caractères. On peut tout de même parcourir l ensemble du tableau en utilisant une boucle foreach. exemples/php1/ex06_tableaux_keystring.php 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 outputentetehtml5 ( Tableaux 2, UTF 8, mystyle. css ) ; 5?> 6 <p> 7 <h1>tableau avec c l é de type S t r i n g</h1> 8 <p> 9 <?php 77

79 Rémy Malgouyres, Programmation Web 10 $tableau = array ( nom => Caesar, prénom => Jules ) ; 11 echo <ul >\n ; 12 // a c c è s aux éléments : 13 echo <l i >Accès aux éléments du tableau :<br/> ; 14 echo Nom :. $tableau [ nom ]. <br/>\n ; 15 echo Prénom :. $tableau [ prénom ]..<br/></ l i >\n ; // a f f i c h a g e de l ensemble des v a l e u r s du tableau par f o r e a c h : 18 echo <l i >Les v a l e u r s du tableau sont :<br/></ l i >\n ; 19 f o r e a c h ( $tableau as $chaine ) { 20 echo $chaine. ; 21 } 22 echo <br/>\n ; // a f f i c h a g e des c l é s et des v a l e u r s du tableau 25 echo <l i >Les données du tableau sont :<br> ; 26 f o r e a c h ( $tableau as $ c l e => $chaine ) { 27 echo $ c l e. :. $chaine. <br/></ l i >\n ; 28 } 29 echo </ul >\n ; 30?> 31 </p> 32 <?php 33 outputfinfichierhtml5 ( ) ; 34?> 78

80 Chapitre 3 : PHP procédural 3.8 Passage de paramètre à un script PHP Dans l exemple suivant, le premier script passe deux paramètes au second : le titre de la page et le texte à afficher. Nous transmettons ici les paramètres par la méthode GET, la méthode POST, qui a l avantage de ne pas faire apparaître les paramètres dans l URL, est similaire au niveau programmation et sera vue plus loin. L url du second script dans le navigateur est ici : ex08_passages_parametres2.php?texte=bonjour&titre=montitre exemples/php1/ex07_passages_parametres1.php 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 $ t i t r e = Mon t i t r e par défaut ; 5 i f ( i s s e t ($_GET[ t i t r e ] ) ) { 6 $ t i t r e = $_GET[ t i t r e ] ; 7 } 8 outputentetehtml5 ( $ t i t r e, UTF 8, mystyle. css ) ; 9?> 10 <p> 11 Pour l a n c e r l autre s c r i p t avec comme t e x t e 12 <?php 13 $ t e x t e = Bonjour ; 14 echo $ t e x t e ; 15 echo <br/> et comme t i t r e ; 16 $ t i t r e = montitre ; 17 echo $ t i t r e. ; 18 echo <a h r e f= \ ; 19 echo. / ex08_passages_parametres2. php?t e x t e = 20. $ t e x t e 21. &t i t r e= 22. $ t i t r e 23. >c l i q u e z i c i</a> ; 24?>. 25 </p> 79

81 Rémy Malgouyres, Programmation Web 26 <?php 27 outputfinfichierhtml5 ( ) ; 28?> Le second script peut alors récupérer les paramètres texte et titre dans un tableau associatif $_GET. On peut vérifier que les variables texte et titre ont bien été utilisées via la fonction isset. exemples/php1/ex08_passages_parametres2.php 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 $ t i t r e = Mon t i t r e par défaut ; 5 i f ( i s s e t ($_GET[ t i t r e ] ) ) { 6 $ t i t r e = $_GET[ t i t r e ] ; 7 } 8 9 outputentetehtml5 ( $ t i t r e, UTF 8, mystyle. css ) ; 10 11?> 12 <p> 13 <?php // début du script PHP 14 i f ( i s s e t ($_GET[ texte ] ) ) { 15 echo $_GET[ texte ] ; 16 } e l s e { 17 echo Hello World! ; // On a f f i c h e du code HTML s i l a s o r t i e 18 } 19 // f i n du script PHP 20?> 21 </p> 22 <?php 23 outputfinfichierhtml5 ( ) ; 24?> Certains navigateurs ne supportant pas les URL avec des caractères comme des accents ou autres caractères UTF-8 quelconques (notamment le &!!!), si on veut passer une chaîne un peu générale en paramètre, on la codera en une string simple via la fonction htmlentities. Dans l exemple suivant, l URL du second script est : 80

82 Chapitre 3 : PHP procédural texte=l%27%c3%a9t%c3%a9%20va%20%c3%aatre%20chaud%20cette%20ann%c3%a9e\ &titre=passage%20de%20param%c3%a8tres%20avec%20accents%20et%20espaces exemples/php1/ex09_passages_parametres3.php 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 $ t i t r e = Mon t i t r e par défaut ; 5 i f ( i s s e t ($_GET[ t i t r e ] ) ) { 6 $ t i t r e = $_GET[ t i t r e ] ; 7 } 8 outputentetehtml5 ( $ t i t r e, UTF 8, mystyle. css ) ; 9?> 10 <p> 11 Pour l a n c e r l autre s c r i p t s avec comme t e x t e 12 <?php 13 $ t e x t e = L é t é va ê t r e chaud c e t t e année ; 14 echo. $ t e x t e. ; 15 echo <br/> et comme t i t r e ; 16 $ t i t r e = Passage de paramètres avec a c c e n t s et e s p a c e s ; 17 echo. $ t i t r e. ; 18 echo \n<a h r e f= \ ; 19 echo. / ex10_passages_parametres4. php?t e x t e = 20. h t m l e n t i t i e s ( $texte, ENT_COMPAT, UTF 8 ) 21. &t i t r e= 22. h t m l e n t i t i e s ( $ t i t r e, ENT_COMPAT, UTF 8 ) 23. \ >\n\ t c l i q u e z i c i \n</a> ; 24?>. 25 </p> 26 <?php 27 outputfinfichierhtml5 ( ) ; 28?> exemples/php1/ex10_passages_parametres4.php 81

83 Rémy Malgouyres, Programmation Web 1 <?php require_once. / commonfunctions. php ;?> 2 3 <?php 4 $ t i t r e = Mon t i t r e par défaut ; 5 i f ( i s s e t ($_GET[ t i t r e ] ) ) { 6 $ t i t r e = html_entity_decode ($_GET[ t i t r e ] ) ; 7 } 8 9 outputentetehtml5 ( $ t i t r e, UTF 8, mystyle. css ) ; 10 11?> 12 <p> 13 <?php // début du script PHP 14 i f ( i s s e t ($_GET[ texte ] ) ) { 15 echo html_entity_decode ($_GET[ texte ] ) ; 16 } e l s e { 17 echo Hello World! ; // On a f f i c h e du code HTML s i l a s o r t i e 18 } 19 // f i n du script PHP 20?> 21 </p> 22 <?php 23 outputfinfichierhtml5 ( ) ; 24?> 3.9 Variables Locales ou Globales, Références exemples/php1/ex11_porteevariables.php 1 <?php require_once. / commonfunctions. php ; 2 3 outputentetehtml5 ( Portée des V a r i a b l e s, UTF 8, mystyle. css ) ; 4?> 5 <h1>v a r i a b l e s l o c a l e s et g l o b a l e s</h1> 6 <?php 7 // D é c l a r a t i o n d une v a r i a b l e g l o b a l e 82

84 Chapitre 3 : PHP procédural 8 $a = Contenu i n i t i a l de l a v a r i a b l e g l o b a l e ; 9 10 // Fonction avec une v a r i a b l e l o c a l e homonyme 11 f u n c t i o n myfunctionwithlocalvariable ( ) { 12 $a = Contenu de l a v a r i a b l e a f f e c t é dans l a f o n c t i o n ; // v a r i a b l e l o c a l e $a 13 } f u n c t i o n myfunctionwithglobalvariableaccess ( ) { 16 g l o b a l $a ; // a c c è s à l a v a r i a b l e g l o b a l e $a 17 $a = Contenu de l a v a r i a b l e a f f e c t é dans l a f o n c t i o n ; 18 } myfunctionwithlocalvariable ( ) ; 21 echo Contenu de l a v a r i a b l e <code>a</code> après l a f o n c t i o n <code> myfunctionwithlocalvariable </code>&nbsp ; :<br/>. $a. <br/> ; 22 myfunctionwithglobalvariableaccess ( ) ; 23 echo Contenu de l a v a r i a b l e <code>a</code> après l a f o n c t i o n <code> myfunctionwithglobalvariableaccess </code>&nbsp ; :<br/>. $a. <br/> ; 24?> 25 <?php 26 outputfinfichierhtml5 ( ) ; 27?> exemples/php1/ex12_passageparreference.php 83

85 Rémy Malgouyres, Programmation Web 1 <?php require_once. / commonfunctions. php ; 2 3 outputentetehtml5 ( Portée des V a r i a b l e s, UTF 8, mystyle. css ) ; 4?> 5 <h1>passage par Référence et par Valeur</h1> 6 <?php 7 // D é c l a r a t i o n d une v a r i a b l e g l o b a l e 8 $a = Contenu i n i t i a l de l a v a r i a b l e g l o b a l e ; 9 10 // Fonction avec une v a r i a b l e l o c a l e homonyme 11 f u n c t i o n myfunctionwithlocalvariable ($myparam) { 12 $myparam = Contenu de l a v a r i a b l e a f f a c t é dans l a f o n c t i o n ; 13 } f u n c t i o n myfunctionwithglobalvariableaccess(&$myparam) { $myparam = Contenu de l a v a r i a b l e a f f e c t é dans l a f o n c t i o n ; 18 } myfunctionwithlocalvariable ( $a ) ; 21 echo Contenu de l a v a r i a b l e <code>a</code> après l a f o n c t i o n <code> myfunctionwithlocalvariable </code>&nbsp ; :<br/>. $a. <br/> ; 22 myfunctionwithglobalvariableaccess ( $a ) ; 23 echo Contenu de l a v a r i a b l e <code>a</code> après l a f o n c t i o n <code> myfunctionwithglobalvariableaccess </code>&nbsp ; :<br/>. $a. <br/> ; 24?> 25 <?php 26 outputfinfichierhtml5 ( ) ; 27?> 84

86 Chapitre 4 Les classes en PHP La programmation objet permet, en développant une bonne fois pour toutes un ensemble de classes appelé framework, de simplifier grandement le travail de développement et de maintenance de logiciels complexes, de manière que ces logiciels soient facilement adaptables. Ainsi, une entreprise telle qu une société de services, d un client à l autre, reprendra tel quel une grande partie de son code, sans même le retoucher. Ce code doit avoir une interface de développement, c est à dire qu il doit mettre à disposition des développeurs un ensemble de méthodes qui permettent de réaliser toutes les tâches de base dont le programmeur peut avoir besoin pour développer chaque application particulière. Les caractéristiques d un framework doivent être : 1. Robustesse : les classes de base du framework doivent être testées et doivent être conçus pour réduire le risque de bugs lorsqu un développer utilise les classes du framework, ou d attaques lorsqu un utilisateur malveillant utilise un site construit à partir du framework. 2. Généricité et versatilité : Le code doit pouvoir s adapter, sans le retoucher, au plus grand nombre d applications possibles. 3. Facilité de maintenance du framework lui-même, avec une modularité interne. Les grand outils (librairies, Frameworks externes, etc.) utilisés par le framework doivent etre circonscrits à des sous-modules avec des wrappers ou helpers de manière à pouvoir changer l un de ces outils sans revoir l ensemble du code. 4. Une bonne lisibilité et une bonne documentation, notamment parce que les développeurs qui utilisent le framework ne sont pas nécessairement les mêmes que les développeurs du framework lui-même. Par rapport à ces quatre objectifs, des outils sont à disposition des développeurs du framework : 1. Robustesse : la visibilité des variables et des méthodes (variables et méthodes privées, protected ou publiques) permet au développeur du framework de garantir que l utilisateur du framework n ira pas faire des bêtises en rentrant dans le code du framework, ce qui pourrait amener les instances de classes du framework dans un état incohérent. 2. Généricité : les patrons de conception (ou design patterns) permettent de développer des interfaces pour le framework qui rendent les code similaire d une application à l autre et qui permet de séparer différents aspects du développement d une application. 85

87 Rémy Malgouyres, Programmation Web 3. Facilité de maintenance du framework : la conception UML permet d avoir une vision schématique du framework, qui peut souvent contenir des centaines de classes. Chaque classe est si possible très simple et la complexité se situe dans la communication entre classes. La réécriture ou la modification d une classe demande alors une intervention limitée, et ne doit pas affecter les autres classes, pourvu que l interface entre les classes reste la même. 4. Lisibilité : une forme stéréotypée pour l interface des classes, les identificateurs, etc. rend le code plus lisible. De plus, des outils permettent de générer automatiquement une documentation (HTML, LATEX, PDF, etc.) des classes à partir de commentaires dans le code. C est le cas par exemple de Doxygen pour le PhP. 4.1 Exemples de classes PHP Classes de Base Un classe doit permettre de manipuler un certain type d objets. La classe doit permettre de représenter les caractéristiques des objets, à travers un certain nombre d attributs, qui sont les variables communes à chacun des objets de ce type. La classe doit aussi permettre à un développeur qui l utilise de réaliser toutes les opération nécessaires sur ces objets, à traves des méthodes. Les méthodes d une classe sont les fonctions qui opèrent en interne sur la classe. La manipulation des attributs se fait presque systématiquement à travers des méthodes, cet qui évite que l utilisateur de la classe ne mette les attributs dans un état incohérent (exemple : variables NULL alors qu elle n est pas censée l être, ce qui génère un bug). Pour celà, on met les attributs privés, c est à dire que seules les méthodes de la classe peuvent accéder à ces attributs. Pour les autres classes, ces attributs ne sont pas visibles : elle ne peuvent pas y accéder directement mais uniquement à travers des méthodes. Voici un exemple avec une classe contenant le numéro de téléphone d une personne. Les commentaires ont une forme spéciale pour pouvoir générer la documentation du code avec l outil Doxygen. Les attributs sont privés et sont toujours initialisés via les setters, qui sont des méthodes spacialement conçues qui testent les condition que doivent satisfaire les attributs (ici être non null) avant des les initialiser. Le constructeur utilise les setters ce qui a l avantage de factoriser le code, c est à dire que les tests sur les valeurs des attributs ne sont réalisés qu une seule fois. exemples/php2/ex01_classetelephone.php 1 <?php 2 namespace People \ Contact ; 3 4 class Telephone { 5 /** Numéro de téléphone, ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 6 p r i v a t e $numero ; 7 /** L i b e l l é du nuéro de téléphone ( domicile, t r a v i l, mobile, e t c ). 8 * Ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 9 p r i v a t e $ l i b e l l e ; Accesseur : permet d o b t e n i r l e numéro de téléphone. */ 12 p u b l i c f u n c t i o n getnumero ( ) { 13 return $ t h i s >numero ; 86

88 Chapitre 4 : Les classes en PHP 14 } Accesseur : permet d o b t e n i r l e l i b e l l é du téléphone */ 17 p u b l i c f u n c t i o n g e t L i b e l l e ( ) { 18 return $ t h i s >l i b e l l e ; 19 } S e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e numéro de téléphone 22 $numero l e numéro de téléphone à u t i l i s e r. peut ê t r e n u l l. 23 * */ 24 p u b l i c f u n c t i o n setnumero ( $numero ) { 25 i f ( empty ( $numero ) ) 26 $ t h i s >numero = ; 27 e l s e 28 $ t h i s >numero = $numero ; 29 } S e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e l i b e l l é de téléphone 32 $numero l e l i b e l l é de téléphone à u t i l i s e r. peut ê t r e n u l l. 33 * */ 34 p u b l i c f u n c t i o n s e t L i b e l l e ( $ l i b e l l e ) { 35 i f ( empty ( $ l i b e l l e ) ) 36 $ t h i s >l i b e l l e = ; 37 e l s e 38 $ t h i s >l i b e l l e = $ l i b e l l e ; 39 } Constructeur : permet de c o n s t r u i r e et d i n i t i a l i s e r un Objet Telephone 42 * Appelle systématiquement l e s s e t t e r s. 43 */ 44 p u b l i c f u n c t i o n construct ( $ l i b e l l e, $numero ) { 45 $this >s e t L i b e l l e ( $ l i b e l l e ) ; 46 $this >setnumero ( $numero ) ; 47 } /** 50 Méthode de g é n é r a t i o n d HTML. Permet d a f f i c h e r un téléphone en HTML. 51 * Les a t t r i b u t s doivent ê t r e non n u l l. ( mais normalement ça ne r i s q u e pas d a r r i v e r 52 * car l e s a t t r i b u t s sont p r i v é s donc l u t i l i s a t e u r de l a c l a s s e n a pas pu l e s mettre à n u l l. 53 * Les s e t t e r s et l e c o n s t r u c t e u r e s t a i n s i conçu que l e s a t t r i b u t s ne peuvent pas ê t r e n u l l. ) 54 * La méthode retourne l e code HTML. 55 */ 56 p u b l i c f u n c t i o n tohtml( ) { 57 return $ t h i s >l i b e l l e. &nbsp ; :. $ t h i s >numero ; 58 } 59 } 60?> Comme on le voit, la classe Telephone fait partie d un sous-namespace People\Contact 87

89 Rémy Malgouyres, Programmation Web du namespace People. Les namespace sou un bon mayen en PHP de réaliser un package, au sens de la conception objet Structuration des Objets, Vues Nous allons maintenant voir une classe un peu plus complexe, au moins en ce sens qu elle possède plus d attributs. Nous allons voir comment nous pouvons, dès ce stade de la conception, respecter un certain nombre de bonnes pratiques, à la fois dans l organisation du code et pour sa division en fichiers, mais aussi, au niveau de la Conception Objet dans la séparation du modèle de données (objetsmétier) et de la mise en forme de ces données pour l affichage vers l utilisateur (vues). Figure 4.1 : Diagramme de Classes du Package People\Contact La classe Adresse représentera le modèle de données pour une adresse postale et la classe AdresseView implémentera (en l occurrence) deux vues HTML d une Adresse, l une développée et l autre compacte. Comme toujours, notre modélisation n est pas cannonique et plusieurs choix seraient possibles. Par ailleurs, pour limiter la longueur des fichiers sources, nous utilisons un trait. Un trait permet de regrouper dans un fichiers séparé un ensemble de méthodes qui font partie d une classe. Un trait peut meme définir une parte de plusieurs classes, mais les méthodes de ces classes doivent avoir exactement le meme code. (c est une manière un peu bricole de faire de la programmation générique en PHP. Dans notre exemple, le trait AdresseProperties contient tous les getters et setters de la classe Adresse. Le trait et ses méthodes sont insérés dans la classe Adresse avec le mot clé use. Nous développons maintenant le code PHP de la classe Adresse. exemples/php2/ex02_classeadresse.php 1 <?php 2 namespace P eop le \ Contact ; 3 r e q u i r e _ o n c e ( dirname ( FILE ). / e x 0 3 _ c l a s s e A d r e s s e P r o p e r t i e s T r a i t. php ) ; 4 5 b r i e f La c l a s s e a d r e s s e c o n t i e n t l a d r e s s e d une p e r s o n n e 6 ( q u i peut ê t r e un c l i e n t, un employé, un f o u r n i s s e u r, e t c... ) 7 */ 8 class Adresse { 9 /** Numéro dans l a rue, ne d o i t pas ê t r e n u l l mais peut ê t r e v i d e */ 88

90 Chapitre 4 : Les classes en PHP 10 p r o t e c t e d $numerorue ; 11 /** Nom de l a rue, ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 12 p r o t e c t e d $rue ; 13 /** Complément ( l i e u dit, e t c. ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 14 p r o t e c t e d $complementaddr ; 15 /** code p o s t a l */ 16 p r o t e c t e d $codepostal ; 17 /** nom de l a v i l l e. ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 18 p r o t e c t e d $ v i l l e ; 19 /** nom du pays. ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 20 p r o t e c t e d $pays ; // I n c l u s i o n du t r a i t A d r e s s e P r o p e r t i e s d é f i n i s s a n t l e s a c c e s s e u r s et s e t t e r s 23 use A d r e s s e P r o p e r t i e s ; Constructeur : i n i t i a l i s e l e s a t t r i b u t s à p a r t i r des paramètres. 26 * Les paramètres correspondent aux v a l e u r s à mettre dans l e s a t t r i b u t s. 27 * Tout o b j e t d o i t ê t r e i n i t i a l i s é avec l e c o n s t r u c t e u r ( appel à new ). 28 * I c i, l e s paramètres peuvent ê t r e n u l l. Les a t t r i b u t s sont a l o r s i n i t i a l i s é s 29 * à une chaîne vide, permettant l a cohérence de l a c l a s s e. 30 */ 31 p u b l i c f u n c t i o n construct ( $numerorue=, $rue=, $complementaddr=, 32 $codepostal=, $ v i l l e=, $pays = France ) { 33 $ t h i s >setnumerorue ( $numerorue ) ; 34 $ t h i s >setrue ( $rue ) ; 35 $ t h i s >setcomplementaddr ( $complementaddr ) ; 36 $ t h i s >setcodepostal ( $codepostal ) ; 37 $ t h i s >s e t V i l l e ( $ v i l l e ) ; 38 $ t h i s >setpays ( $pays ) ; 39 } 40 } // end o f c l a s s Adresse 41?> Voici maintenant le code PHP du trait AdresseProperties. exemples/php2/ex03_classeadressepropertiestrait.php 1 <?php 2 namespace People \ Contact ; 3 /** La c l a s s e a d r e s s e c o n t i e n t l a d r e s s e d une personne 5 ( qui peut ê t r e un c l i e n t, un employé, un f o u r n i s s e u r, e t c... ) 6 */ 7 t r a i t A d r e s s e P r o p e r t i e s { 8 9 Accesseur : permet d o b t e n i r l i d e n t i f i a n t de l i n s t a n c e. */ 10 p u b l i c f u n c t i o n getid ( ) { 11 return $ t h i s >id ; 12 } Accesseur : permet d o b t e n i r l e numéro dans l a rue. */ 15 p u b l i c f u n c t i o n getnumerorue ( ) { 16 return $ t h i s >numerorue ; 17 } Accesseur : permet d o b t e n i r l e nom l a rue. */ 89

91 Rémy Malgouyres, Programmation Web 20 p u b l i c f u n c t i o n getrue ( ) { 21 return $ t h i s >rue ; 22 } Accesseur : permet d o b t e n i r l e nom l e complément d a d r e s s e. */ 25 p u b l i c f u n c t i o n getcomplementaddr ( ) { 26 return $ t h i s >complementaddr ; 27 } Accesseur : permet d o b t e n i r l e nom l e code p o s t a l. */ 30 p u b l i c f u n c t i o n getcodepostal ( ) { 31 return $ t h i s >codepostal ; 32 } Accesseur : permet d o b t e n i r l e nom l a v i l l e. */ 35 p u b l i c f u n c t i o n g e t V i l l e ( ) { 36 return $ t h i s >v i l l e ; 37 } Accesseur : permet d o b t e n i r l e pays. */ 41 p u b l i c f u n c t i o n getpays ( ) { 42 return $ t h i s >pays ; 43 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a rue. $NumeroRue l e numéro à u t i l i s e r. peut ê t r e n u l l. 47 */ 48 p u b l i c f u n c t i o n s e t I d ( $id ) { 49 $ t h i s >id = empty ( $id )? : $id ; 50 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a rue. $NumeroRue l e numéro à u t i l i s e r. peut ê t r e n u l l. 54 */ 55 p u b l i c f u n c t i o n setnumerorue ( $numerorue ) { 56 $ t h i s >numerorue = ( $numerorue == n u l l )? : $numerorue ; 57 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e numéro dans l a rue. $Rue l e nom de l a rue ou de l a p l a c e à u t i l i s e r. peut ê t r e n u l l. 61 */ 62 p u b l i c f u n c t i o n setrue ( $rue ) { 63 $ t h i s >rue = ( $rue == n u l l )? : $rue ; 64 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e complément d a d r e s s e. $ComplementAddr l e complément d a d r e s s e à u t i l i s e r. peut ê t r e n u l l. 68 */ 69 p u b l i c f u n c t i o n setcomplementaddr ( $complementaddr ) { 70 $ t h i s >complementaddr = ( $complementaddr == n u l l )? : $ComplementAddr ; 71 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e code p o s t a l. $CodePostal l e numéro à u t i l i s e r. peut ê t r e n u l l 90

92 Chapitre 4 : Les classes en PHP 75 */ 76 p u b l i c f u n c t i o n setcodepostal ( $codepostal ) { 77 $ t h i s >codepostal = ( $codepostal == n u l l )? : $codepostal ; 78 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a v i l l e. $ V i l l e l e nom de l a v i l l e à u t i l i s e r. peut ê t r e n u l l 82 */ 83 p u b l i c f u n c t i o n s e t V i l l e ( $ v i l l e ) { 84 $ t h i s >v i l l e = ( $ v i l l e == n u l l )? : $ v i l l e ; 85 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom du Pays $pays l e nom du Pays à u t i l i s e r. peut ê t r e n u l l 89 */ 90 p u b l i c f u n c t i o n setpays ( $pays ) { 91 $ t h i s >pays = ( $pays == n u l l )? : $pays ; 92 } 93 } 94?> Voici maintenant le code PHP de la classe AdresseView. exemples/php2/ex04_classeadresseview.php 1 <?php 2 namespace People \ Contact ; 3 require_once ( dirname ( FILE ). / ex02_classeadresse. php ) ; /** La c l a s s e AdresseView implémente l a g é n é r a t i o n d HTML pour a f f i c h e r 8 * une a d r e s s e dans une vue dans un navigareur. 9 * Implémente a u s s i des u t i l i s t a i r e s de c o n v e r s i o n à p a r t i r d une Adresse 10 * pour o b t e n i r f a c i l e m e n t l e code HTML pour a f f i c h e r une Adresse. 11 */ 12 class AdresseView { /** 15 Méthode de g é n é r a t i o n d HTML. Permet de g é n é r e r l e code HTML d une a d r e s s e. 16 * Les a t t r i b u t s de l a d r e s s e doivent ê t r e non n u l l. 17 * ( mais normalement ça ne r i s q u e pas d a r r i v e r car l e s a t t r i b u t s sont p r i v é s ) 18 * La méthode retourne l e code HTML avec des r e t o u r à l a l i g n e pour un a f f i c h a g e mis en forme. 19 */ 20 p u b l i c s t a t i c f u n c t i o n gethtmldevelopped ( $ a d r e s s e ) { 21 $htmlcode = ; 22 $htmlcode.= <strong >Adresse : </strong ><br/>\n ; 23 $htmlcode.= $adresse >getnumerorue ( ) ; 24 i f (! empty ( $adresse >getnumerorue ( ) ) ) 25 $htmlcode.=, ; 26 $htmlcode.= $adresse >getrue ( ) ; 27 i f (! empty ( $adresse >getrue ( ) ) ) 28 $htmlcode.= <br/> ; 29 $htmlcode.= $adresse >getcomplementaddr ( ) ; 91

93 Rémy Malgouyres, Programmation Web 30 i f (! empty ( $adresse >getcomplementaddr ( ) ) ) 31 $htmlcode.= <br/> ; 32 $htmlcode.= $adresse >getcodepostal ( ). ; 33 $htmlcode.= $adresse >g e t V i l l e ( ) ; 34 i f (! empty ( $adresse >g e t V i l l e ( ) ) ) 35 $htmlcode.= <br/> ; 36 $htmlcode.= $adresse >getpays ( ). <br/> ; return $htmlcode ; 39 } /** 42 Méthode de g é n é r a t i o n d HTML. Permet d a f f i c h e r une a d r e s s e en HTML. 43 * Les a t t r i b u t s doivent ê t r e non n u l l. ( mais normalement ça ne r i s q u e pas d a r r i v e r 44 * car l e s a t t r i b u t s sont p r i v é s donc l u t i l i s a t e u r de l a c l a s s e n a pas pu l e s mettre à n u l l. 45 * Les s e t t e r s et l e c o n s t r u c t e u r e s t a i n s i conçu que l e s a t t r i b u t s ne peuvent pas ê t r e n u l l. ) 46 * La méthode retourne l e code HTML pour un a f f i c h a g e compact. 47 */ 48 p u b l i c s t a t i c f u n c t i o n gethtmlcompact ( $ a d r e s s e ) { 49 $htmlcode = ; 50 $htmlcode.= $adresse >getnumerorue ( ) ; 51 i f (! empty ( $adresse >getnumerorue ( ) ) ) 52 $htmlcode.=, ; 53 $htmlcode.= $adresse >getrue ( ) ; 54 i f (! empty ( $adresse >getrue ( ) ) ) 55 $htmlcode.=, ; 56 $htmlcode.= $adresse >getcomplementaddr ( ) ; 57 i f (! empty ( $adresse >getcomplementaddr ( ) ) ) 58 $htmlcode.=, ; 59 $htmlcode.= $adresse >getcodepostal ( ). ; 60 $htmlcode.= $adresse >g e t V i l l e ( ) ; 61 i f (! empty ( $adresse >g e t V i l l e ( ) ) ) 62 $htmlcode.=, ; 63 $htmlcode.= $adresse >getpays ( ) ; return $htmlcode ; 66 } 67 } // end o f c l a s s AdresseView 68?> Utilisation des Classes et Vue HTML Voyons maintenant un petit script de test qui crée des adresses et les affiche en générant une vue HTML. Seul le script de test génère du code HTML et comporte un en-tête HTML (même si ce code HTML est en fait généré dans une méthode statique de la classe AdresseView). exemples/php2/ex05_testexampleimportnamespace.php 1 <?php 2 require_once ( dirname ( FILE ). / ex01_classetelephone. php ) ; 3 require_once ( dirname ( FILE ). / ex04_classeadresseview. php ) ; 92

94 Chapitre 4 : Les classes en PHP 4 5 u s e People \ Contact a s Contact ; 6 7 $telephone = new Contact \ Telephone ( T r a v a i l, ) ; // Adresse Complète : 11 $ a d r e s s e 1 = new Contact \ Adresse ( 1 0, a l l é e du net, Quartier de l \ avenir, , Clermont Ferrand ) ; // Adresse sans code p o s t a l ni complément d a d r e s s e 15 $ a d r e s s e 2 = new Contact \ Adresse ( 1 0, Downing Street, null, 16 null, London, United Kingdom ) ; // Génération du code HTML ( vue ) 19 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 20 outputentetehtml5 ( Ma première c l a s s e PHP, UTF 8, mystyle. css ) ; echo <h1>test de Classe </h1> ; 23 echo <p> ; 24 echo <strong >Téléphone </strong >. $telephone >tohtml( ). <br/> ; 93

95 Rémy Malgouyres, Programmation Web echo <strong >Adresse au format compact</strong > &nbsp ; :<br/>. 27 Contact \ AdresseView : :gethtmlcompact ( $ a d r e s s e 1 ). <br/> ; 28 echo Contact \ AdresseView : :gethtmldevelopped ( $ a d r e s s e 2 ). <br/> ; // Adresse vide!!! 31 $ a d r e s s e 3 = new Contact \ Adresse ( ) ; 32 echo <strong >Adresse vide&nbsp ; :</ strong ><br/> 33. Contact \ AdresseView : :gethtmlcompact ( $ a d r e s s e 3 ). <br/> ; 34 echo </p> ; outputfinfichierhtml5 ( ) ; 37?> 4.2 Validation en entrée et gestion d une exception Qu est-ce que le filtrage? Les setters de la classe vont jouer un rôle important de filtrage des données. Le filtrage consiste à réaliser des tests sur les données entrées (généralement des données issues d un utilisateur final), et à générer des erreurs en cas de données incorrectes, ou encore en remplaçant automatiquement des données incorrecte par des données, sinon correctes, au moins inoffensives. En particulier, lorsque les données viendront de la saisie d un formulaire, ces données devront être systématiquement filtrées car l utilisateur, qui n est pas toujours bienveillant, et peut mettre n importe quoi dans les champs d un formulaire. Le filtrage jouera donc un rôle très important pour la sécurité. Par exemple, on prendra soin de limiter la longueur des attributs de type String à la fois au niveau du filtrage, puis au niveau de la base de données (voir chapitres ultérieurs). On pourra aussi utiliser des expressions régulières lors du filtrage grâce aux fonctions preg_match_all ou preg_match (voir man regex(7) pour la formation des expressions régulières). Le gros avantage du PHP par rapport à d autres langages comme javascript, est que PHP s exécute côté serveur donc un pirate n aura pas la possibilité d analyser précisément ce que fait le filtrage. Si une valeur invalide est détectée au niveau du filtrage, on générera une exception avec un message d erreur. Cette exception pourra être gérée à un autre niveau dans l application, ici au niveau du script de test qui affiche quelques employés. Certaines parties ultérieures de ce cours sont dédiées au filtrage précis des données et à garantir la sécurité du code grâce au filtrage. Dans cette partie, nous réalisons un filtrage sommaire, pour illustrer le mecanisme de gestion des erreurs par exceptions Le Package People\Individuals Classe Personne avec filtrage dans les setters Nous voyons ici une classe Personne, suivant un peu le meme schéma de conception que la classe Adresse de la partie précédente. Cependant, au niiveau des setters, nous implémenterons un filtrage (minimal et peu réaliste pour le moment), rejetant une exception en cas de données incorrectes. exemples/php2/ex07_classepersonne.php 94

96 Chapitre 4 : Les classes en PHP Figure 4.2 : Diagramme de Classes du Package People\Individuals 1 <?php 2 namespace Pe op le \ I n d i v i d u a l s ; 3 r e q u i r e _ o n c e ( dirname ( FILE ). / e x 0 8 _ c l a s s e P e r s o n n e P r o p e r t i e s T r a i t. php ) ; 4 r e q u i r e _ o n c e ( dirname ( FILE ). / e x 0 1 _ c l a s s e T e l e p h o n e. php ) ; 5 6 u s e P eop le \ Contact \ A d r e s s e ; 7 u s e P eop le \ Contact \ Telephone ; 8 9 /** b r i e f La c l a s s e Personne r e p r é s e n t e une p e r s o n n e ( c l i e n, employé, f o u r n i s s e u r, contact... ). 11 E l l e c o n t i e n t l i d e n t i t é (nom prénom ), l a d r e s s e, l e noméro de t é l é p h o n e 12 e t l e s a l a i r e mensuel de l employé. 13 */ 14 c l a s s Personne { 15 /** nom de l employé : o b l i g a t o i r e. Le nom de l employé ne peut pas ê t r e n u l l ou v i d e. */ 16 p r o t e c t e d $nom ; 17 /** prénom de l employé */ 18 p r o t e c t e d $prenom ; 19 /** a d r e s s e de l employé */ 20 protected $adresse ; 21 /** Tableau d e s numéros de t é l é p h o n e */ 22 protected $telephones ; use PersonneProperties ; /** Constructeur : i n i t i a l i s e l e s a t t r i b u t s à p a r t i r des paramètres. 95

97 Rémy Malgouyres, Programmation Web 28 Les paramètres correspondent aux v a l e u r s à mettre dans l e s a t t r i b u t s. 29 Tout o b j e t d o i t ê t r e i n i t i a l i s é avec l e c o n s t r u c t e u r ( appel à new ). 30 Des e x c e p t i o n s sont r e j e t é e s en cas de paramètres i n v a l i d e. 31 */ 32 p u b l i c f u n c t i o n construct ($nom, $prenom, $adresse, $ t e l e p h o n e s ) { $ t h i s >setnom ($nom) ; 35 $ t h i s >setprenom ( $prenom ) ; 36 $ t h i s >s e t A d r e s s e ( $ a d r e s s e ) ; $ t h i s >settelephones ( $ t e l e p h o n e s ) ; 39 } 40 } 41?> exemples/php2/ex08_classepersonnepropertiestrait.php 1 <?php 2 namespace People \ I n d i v i d u a l s ; 3 require_once. / ex02_classeadresse. php ; use People \ Contact \ Telephone ; 7 use People \ Contact \ Adresse ; 8 9 t r a i t PersonneProperties { 10 a c c e s s e u r : permet d o b t e n i r l e nom de l employé */ 11 p u b l i c f u n c t i o n getnom ( ) { 12 return $ t h i s >nom ; 13 } a c c e s s e u r : permet d o b t e n i r l e prénom de l employé */ 16 p u b l i c f u n c t i o n getprenom ( ) { 17 return $ t h i s >prenom ; 18 } a c c e s s e u r : permet d o b t e n i r l a d r e s s e de l employé */ 21 p u b l i c f u n c t i o n getadresse ( ) { 22 return $ t h i s >a d r e s s e ; 23 } a c c e s s e u r : permet d o b t e n i r l e tableau des t é l é p h o n e s de l employé */ 26 p u b l i c f u n c t i o n gettelephones ( ) { return $ t h i s >t e l e p h o n e s ; 29 } a c c e s s e u r : permet d o b t e n i r un numéro de téléphone de l employé */ 32 p u b l i c f u n c t i o n gettelephone ( $ l i b e l l e ) { 33 i f ( empty ( $ t h i s >telephone [ $ l i b e l l e ] ) ) { 34 throw new \ Exception ( Désolé, Le téléphone. $ l i b e l l e. n \ e x i s t e pas. Have a try in the phonebook... ) ; 35 } 36 return $ t h i s >telephone [ $ l i b e l l e ] ; 37 } 96

98 Chapitre 4 : Les classes en PHP 38 /** s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a personne $Nom l e nom de l a personne. Doit ê t r e non n u l l et comporter 40 au moins 1 c a r a c t è r e. 41 */ 42 p u b l i c f u n c t i o n setnom ($nom) { 43 i f ( empty ($nom) s t r l e n ($nom) > 100) { 44 throw new \ Exception ( Désolé, toute personne d o i t a v o i r un nom et l e nom a au plus 100 c a r a c t è r e s! ) ; 45 } e l s e { 46 $ t h i s >nom = $nom ; 47 } 48 } /** s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a personne */ 51 p u b l i c f u n c t i o n setprenom ( $prenom ) { 52 i f ( empty ( $prenom ) s t r l e n ( $prenom ) > 50) { 53 throw new \ Exception ( Désolé, toute personne d o i t a v o i r un prenom et l e prenom a au plus 50 c a r a c t è r e s! ) ; 54 } e l s e { 55 $ t h i s >prenom = $prenom ; 56 } 57 } /** s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l a d r e s s e de l a personne */ 60 p u b l i c f u n c t i o n s e t A d r e s s e ( $ a d r e s s e ) { 61 i f ( $ a d r e s s e == n u l l g e t _ c l a s s ( $ a d r e s s e )!= People \ Contact \ Adresse ) { 62 throw new \ Exception ( Erreur : Adresse I n v a l i d e ) ; 63 } e l s e { 64 $ t h i s >a d r e s s e = $ a d r e s s e ; 65 } 66 } /** s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l a d r e s s e de l a personne */ 69 p u b l i c f u n c t i o n settelephones ( $ t e l e p h o n e s ) { 70 i f (! is_array ( $ t e l e p h o n e s ) ) { 71 throw new \ Exception ( Erreur : Téléphones I n v a l i d e ) ; 72 } e l s e { 73 $ t h i s >t e l e p h o n e s = $ t e l e p h o n e s ; 74 } 75 } /** s e t t e r : permet d a j o u t e r un numéro de téléphone de l a personne */ 78 p u b l i c f u n c t i o n addtelephone ( $ l i b e l l e, $numero ) { 79 i f (! empty ( $numero ) && s t r l e n ( $numero ) <= 15) { 80 i f (! is_array ( $ t h i s >t e l e p h o n e s ) ) { 81 $ t h i s >t e l e p h o n e s = array ( ) ; 82 } 83 $ t h i s >t e l e p h o n e s [ $ l i b e l l e ] = new Telephone ( $ l i b e l l e, $numero ) ; 84 } e l s e { 85 throw new \ Exception ( Erreur : Téléphone I n v a l i d e ) ; 86 } } /** s e t t e r : permet d a j o u t e r un numéro de téléphone de l a personne */ 91 p u b l i c f u n c t i o n removetelephone ( $ l i b e l l e ) { 97

99 Rémy Malgouyres, Programmation Web 92 i f (! empty ( $ t h i s >telephone [ $ l i b e l l e ] ) ) { 93 unset ( $ t h i s >telephone [ $ l i b e l l e ] ) ; 94 } 95 } } 98?> exemples/php2/ex09_classepersonneview.php 1 <?php 2 namespace People \ I n d i v i d u a l s ; 3 require_once ( dirname ( FILE ). / ex04_classeadresseview. php ) ; 4 require_once ( dirname ( FILE ). / ex07_classepersonne. php ) ; 5 6 use People \ Contact \ Adresse ; 7 u s e People \ Contact \ AdresseView ; 8 9 class PersonneView { /** Méthode de g é n é r a t i o n d une vue HTML. Permet d a f f i c h e r une a d r e s s e en HTML. 13 Les a t t r i b u t s doivent ê t r e non n u l l. ( mais normalement ça ne r i s q u e pas d a r r i v e r 14 car l e s a t t r i b u t s sont p r i v é s donc l u t i l i s a t e u r de l a c l a s s e n a pas pu l e s mettre à n u l l. 15 Les s e t t e r s et l e c o n s t r u c t e u r e s t a i n s i conçu que l e s a t t r i b u t s ne peuvent pas ê t r e n u l l. ) 16 */ 17 p u b l i c s t a t i c f u n c t i o n gethtmldevelopped ( $personne ) { 18 $htmlcode = ; 19 $htmlcode.= nom :. $personne >getnom ( ). <br/>\n ; 20 i f ( s t r l e n ( $personne >getprenom )>=1) 21 $htmlcode.= Prénom :. $personne >getprenom ( ). <br/>\n ; 22 $htmlcode.= AdresseView : :gethtmldevelopped ( $personne >getadresse ( ) ) ; 23 $count = 0 ; 24 f o r e a c h ( $personne >gettelephones ( ) as $telephone ) { 25 i f ( $count!= 0) { 26 $htmlcode.= <br/> ; 27 } 28 $count++ ; 29 $htmlcode.= $telephone >tohtml( ) ; 30 } 31 $htmlcode.= <br/>\n ; 32 return $htmlcode ; 33 } /** Méthode de g é n é r a t i o n d une vue l i g n e de tablehtml. Permet d a f f i c h e r des Personnes 37 dans une t a b l e HTML. 38 */ 39 p u b l i c s t a t i c f u n c t i o n gethtmltablerow ( $personne ) { 40 $htmlcode = <t r > ; 41 $htmlcode.= <td>. $personne >getnom ( ). </td> ; 98

100 Chapitre 4 : Les classes en PHP 42 $htmlcode.= <td>. $personne >getprenom ( ). </td> ; 43 $htmlcode.= <td>. AdresseView : :gethtmlcompact ( $personne >getadresse ( ) ). </ td> ; 44 $htmlcode.= <td> ; 45 $count = 0 ; 46 f o r e a c h ( $personne >gettelephones ( ) as $telephone ) { 47 i f ( $count!= 0) { 48 $htmlcode.= <br/> ; 49 } 50 $count++ ; 51 $htmlcode.= $telephone >tohtml( ) ; 52 } 53 $htmlcode.= </td> ; 54 $htmlcode.= </ t r > ; return $htmlcode ; 57 } /** 62 * Permet d o b t e n i r une l i g n e de t a b l e HTML avec l e s en t ê t e s de c o l o n n e s 63 * pour a f f i c h a g e d une t a b l e de Personnes. 64 * */ 65 p u b l i c s t a t i c f u n c t i o n gethtmltableheads ( ) { 66 $htmlcode = <t r > ; 67 $htmlcode.= <th>nom</th> ; 68 $htmlcode.= <th>prénom</th> ; 69 $htmlcode.= <th>adresse </th> ; 70 $htmlcode.= <th>téléphone ( s )</th> ; 71 $htmlcode.= </ t r > ; 72 return $htmlcode ; 73 } 74 } // end o f c l a s s PersonneView 75?> Test de construction de Personnes et récupération des exceptions Voyons tout d abord la construction normale et l affichage d une personne. exemples/php2/ex10_testpersonnes.php 1 <?php 2 require_once ( dirname ( FILE ). / ex01_classetelephone. php ) ; 3 require_once ( dirname ( FILE ). / ex02_classeadresse. php ) ; 4 require_once ( dirname ( FILE ). / ex04_classeadresseview. php ) ; 5 require_once ( dirname ( FILE ). / ex09_classepersonneview. php ) ; 6 7 use People \ Contact \ Adresse ; 8 u s e People \ Contact \ AdresseView ; 9 use People \ Contact \ Telephone ; 10 use People \ I n d i v i d u a l s \ Personne ; 11 use People \ I n d i v i d u a l s \ PersonneView ; 12 99

101 Rémy Malgouyres, Programmation Web 13 try { 14 $ a d r e s s e = new Adresse ( 1 0, a l l é e du net, Quartier de l \ avenir, , Clermont Ferrand ) ; 16 $ t e l e p h o n e s = array (new Telephone ( Domicile, ), 17 new Telephone ( Mobile, ) ) ; 18 $personne = new Personne ( Obama, Barack, $adresse, $ t e l e p h o n e s ) ; // La personne a bien é t é c o n s t r u i t e, on a f f i c h e 21 r e q u i r e ( ex10_vuenormale. php ) ; 22 } catch ( Exception $e ) { 23 // Une e r r e u r s e s t produite, on l a gère 24 r e q u i r e ( ex10_vueerreur. php ) ; 25 } 26 27?> exemples/php2/ex10_vuenormale.php 1 <?php 2 use People \ I n d i v i d u a l s \ PersonneView ; 3 require_once ( commonfunctions. php ) ; 4 outputentetehtml5 ( Construction et f f i c h a g e d \ une Personne, UTF 8, mystyle. css ) ; 5 6 echo <p> ; 7 echo PersonneView : :gethtmldevelopped ( $personne ) ; 8 echo </p> ; 9 10 outputfinfichierhtml5 ( ) ; 11?> exemples/php2/ex10_vueerreur.php 100

102 Chapitre 4 : Les classes en PHP 1 <?php 2 require_once ( commonfunctions. php ) ; 3 outputentetehtml5 ( Gestion d \ une exception, UTF 8, mystyle. css ) ; 4 5 echo <h1>une Erreur c e s t produite </h1> ; 6 echo <p>exception reçue :. $e >getmessage ( ). </p> ; 7 8 outputfinfichierhtml5 ( ) ; 9?> Voyons maintenant le test d une vue affichant plusiers personnes dans une table HTML. exemples/php2/ex11_testtableviewpersonnes.php 1 <?php 2 require_once ( dirname ( FILE ). / ex01_classetelephone. php ) ; 3 require_once ( dirname ( FILE ). / ex02_classeadresse. php ) ; 4 require_once ( dirname ( FILE ). / ex04_classeadresseview. php ) ; 5 require_once ( dirname ( FILE ). / ex09_classepersonneview. php ) ; 6 7 use People \ Contact \ Adresse ; 8 u s e People \ Contact \ AdresseView ; 9 use People \ Contact \ Telephone ; 10 use People \ I n d i v i d u a l s \ Personne ; echo <p> ; 13 try { 14 $ a d r e s s e 1 = new Adresse ( 1 0, a l l é e du net, Quartier de l \ avenir, , Clermont Ferrand ) ; 16 $ t e l e p h o n e s 1 = array (new Telephone ( Domicile, ) ) ; 17 $personne1 = new Personne ( Obama, Barack, $adresse1, $ t e l e p h o n e s 1 ) ; 18 $ a d r e s s e 2 = new Adresse ( 1 2, Georgy, null, 63000, Trench Town, Jamaica ) ; 19 $ t e l e p h o n e s 2 = array (new Telephone ( Emergency, 911 ) ) ; 20 $personne2 = new Personne ( Modèle, Jean, $adresse2, $ t e l e p h o n e s 2 ) ; 21 $ a d r e s s e 3 = new Adresse ( 1 0, Rock \ n Roll Street, Bronx, 63000, Rackamadour ) ; 22 $personne3 = new Personne ( Génération, igrec, $adresse3, 23 array (new Telephone ( T r a v a i l, ) ) ) ; 24 $personnes = array (1 => $personne1, 2 => $personne2, 3 => $personne3 ) ;

103 Rémy Malgouyres, Programmation Web 26 r e q u i r e ( ex11_vuenormale. php ) ; 27 } catch ( Exception $e ) { 28 r e q u i r e ( ex10_vueerreur. php ) ; 29 } 30?> exemples/php2/ex11_vuenormale.php 1 <?php 2 use People \ I n d i v i d u a l s \ PersonneView ; 3 4 require_once ( commonfunctions. php ) ; 5 6 outputentetehtml5 ( Gestion d \ une exception, UTF 8, mystyle. css ) ; 7 echo <strong >A f f i c h a g e d une t a b l e de Personnes&nbsp ; :</ strong ><br/> ; 8 echo <table > ; 9 echo <thead>. PersonneView : :gethtmltableheads ( ). </thead> ; 10 echo <tbody> ; 11 f o r e a c h ( $personnes as $personne ) { 12 echo PersonneView : :gethtmltablerow ( $personne ) ; 13 } 14 echo </tbody> ; 15 echo </table > ; 16 outputfinfichierhtml5 ( ) ; 17?> Voyons enfin ce qui se passe lorsqu une erreur dans les données déclenche une exception au niveau du setter, alors que notre récupération de l exception nous permet d afficher un message d erreur intelligible, évitant le crash complet du site. exemples/php2/ex12_testexceptionspersonnes.php 1 <?php 2 require_once ( commonfunctions. php ) ; 3 require_once ( dirname ( FILE ). / ex01_classetelephone. php ) ; 4 require_once ( dirname ( FILE ). / ex02_classeadresse. php ) ; 5 require_once ( dirname ( FILE ). / ex04_classeadresseview. php ) ; 6 require_once ( dirname ( FILE ). / ex09_classepersonneview. php ) ; 7 8 use People \ Contact \ Adresse ; 102

104 Chapitre 4 : Les classes en PHP 9 u s e People \ Contact \ AdresseView ; 10 use People \ Contact \ Telephone ; 11 use People \ I n d i v i d u a l s \ Personne ; 12 use People \ I n d i v i d u a l s \ PersonneView ; outputentetehtml5 ( Gestion d \ une exception, UTF 8, mystyle. css ) ; echo <p> ; 17 echo <strong >Test avec r é c u p é r a t i o n s d e x c e p t i o n s&nbsp ; :</ strong ><br/> ; 18 try { 19 $ a d r e s s e 1 = new Adresse ( 1 0, Downing Street, null, 20 null, London, United Kingdom ) ; 21 $personne1 = new Personne ( Thatcher, Marggy, $adresse1, ) ; // phony phone number echo PersonneView : :gethtmldevelopped ( $personne1 ) ; 25 } catch ( Exception $e ) { 26 echo Exception reçue :, $e >getmessage ( ), <br/>\n ; 27 } try { 30 $ a d r e s s e 2 = new Adresse ( 1 0, a l l é e du net, Quartier de l \ avenir, , Clermont Ferrand, Technique ) ; 32 $personne2 = new Personne ( Urluberlu, null, $adresse2, n u l l ) ; // Given name?? 33 echo PersonneView : :gethtmldevelopped ( $personne2 ) ; 34 } catch ( Exception $e ) { 35 echo Exception reçue :, $e >getmessage ( ), \n ; 36 } 37 echo </p> ; outputfinfichierhtml5 ( ) ; 40?> 4.3 Classe Employe héritant de la classe Personne Notons l attribut categoriesemployes, qui répertorie dans un tableau toutes les catégories d employés possibles, et la méthode validcategorie, qui détermine si une chaine de catactères correspond à une catégorie d employés. Cette donnée et cette méthode sont déclarées statiques. Il s agit donc d une variable de classe et d une méthodes de classe. Voici le script de test qui crée quelques employés. Lorsque une exception est reçue, au lieu d afficher l employé, on affiche le message d erreur. Nous verrons plus loin comment ce mécanisme de gestion des exceptions permet de renvoyer à l utilisateur des informations sur les attributs invalides qu il a saisi dans le formulaire. exemples/php2/ex13_classeemploye.php 1 <?php 2 namespace People \ I n d i v i d u a l s \Employees ; 3 require_once ( dirname ( FILE ). / ex07_classepersonne. php ) ; 4 require_once ( dirname ( FILE ). / ex14_classeemployeproperties. php ) ; 5 6 use People \ I n d i v i d u a l s \ Personne ; 7 103

105 Rémy Malgouyres, Programmation Web 8 class Employe extends Personne { 9 10 /** s a l a i r e mensuel de l a personne en euros / mois */ 11 p r o t e c t e d $ s a l a i r e M e n s u e l ; /** c a t é g o r i e de l employé : s e c r é t a i r e, commercial, technique ou pdg */ 14 p r o t e c t e d $ c a t e g o r i e ; tableau de t o u t e s l e s c a t é g o r i e s d employés p o s s i b l e s. 17 un a t t r i b u t s t a t i q u e e s t un a t t r i b u t qui e x i s t e en un s e u l exemplaire 18 commun à tous l e s o b j e t s de l a c l a s s e. 19 Cela é v i t e d a v o i r autant de c o p i e s du tableau $categoriesemployes 20 qu i l y a d i n s t a n c e de l a c l a s s e Employe en mémoire. 21 */ 22 p r i v a t e s t a t i c $categoriesemployes = array ( s e c r é t a i r e, commercial, technique, boss ) ; use EmployeProperties ; p u b l i c f u n c t i o n construct ($nom, $prenom, $adresse, 27 $telephones, $ s a l a i r e, $ c a t e g o r i e ) { 28 parent : : construct ($nom, $prenom, $adresse, $ t e l e p h o n e s ) ; $ t h i s >s e t S a l a i r e M e n s u e l ( $ s a l a i r e ) ; 31 $ t h i s >s e t C a t e g o r i e ( $ c a t e g o r i e ) ; 32 } 33 } 34?> exemples/php2/ex14_classeemployeproperties.php 1 <?php 2 namespace People \ I n d i v i d u a l s \Employees ; 3 4 t r a i t EmployeProperties { 5 6 /** Méthode s t a t i q u e de v a l i d a t i o n d un paramètre de c a t é g o r i e. 7 l a v a l e u r d o i t se trouver dans l e s tableau $categoriesemployes. 8 Une méthode s t a t i q u e e s t une méthode qui ne s applique pas à un o b j e t p a r t i c u l i e r. 9 On l u t i l i s e avec s e l f : : ou à l e x t é r i e u r de l a c l a s s e avec Employe : : 10 */ 11 p u b l i c s t a t i c f u n c t i o n i s V a l i d C a t e g o r i e ( $ c a t e g o r i e ) { 12 i f ( $ c a t e g o r i e == n u l l! i s _ s t r i n g ( $ c a t e g o r i e )! in_array ( $ c a t e g o r i e, s e l f : :$categoriesemployes ) ) { 13 return f a l s e ; 14 } 15 return true ; 16 } a c c e s s e u r : permet d o b t e n i r l a c a t é g o r i e de l employé */ 19 p u b l i c f u n c t i o n g e t C a t e g o r i e ( ) { 20 return $ t h i s >c a t e g o r i e ; 21 }

106 Chapitre 4 : Les classes en PHP 23 a c c e s s e u r : permet d o b t e n i r l e téléphone 1 de l employé */ 24 p u b l i c f u n c t i o n g e t S a l a i r e M e n s u e l ( ) { 25 return $ t h i s >s a l a i r e M e n s u e l ; 26 } /** s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l a c a t é g o r i e de l a personne $Categorie d o i t correspondre à une c a t é g o r i e d employé r é p e r t o r i é e. 30 */ 31 p u b l i c f u n c t i o n s e t C a t e g o r i e ( $ c a t e g o r i e ) { 32 i f (! s e l f : :i s V a l i d C a t e g o r i e ( $ c a t e g o r i e ) ) { 33 throw new \ Exception ( Erreur, c a t é g o r i e d employé \. $ c a t e g o r i e. \ i n v a l i d e. ) ; 34 } e l s e { 35 $ t h i s >c a t e g o r i e = $ c a t e g o r i e ; 36 } 37 } /** s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e s a l a i r e mensuel de l a personne $ S a l a i r e s a l a i r e mensuel en euros / mois 41 */ 42 p u b l i c f u n c t i o n s e t S a l a i r e M e n s u e l ( $ s a l a i r e ) { 43 i f ( $ s a l a i r e == n u l l! is_numeric ( $ s a l a i r e ) ) { 44 $ t h i s >s a l a i r e M e n s u e l = 0. 0 ; 45 } e l s e { 46 $ t h i s >s a l a i r e M e n s u e l = $ s a l a i r e ; 47 } 48 } 49 } 50?> exemples/php2/ex15_classeemployeview.php 1 <?php 2 namespace People \ I n d i v i d u a l s \Employees ; 3 require_once ( dirname ( FILE ). / ex13_classeemploye. php ) ; 4 require_once ( dirname ( FILE ). / ex09_classepersonneview. php ) ; 5 6 use People \ I n d i v i d u a l s \ PersonneView ; 7 8 class EmployeView { 9 10 /** Méthode de g é n é r a t i o n d une vue HTML. Permet d a f f i c h e r un Employe en HTML. 12 Les a t t r i b u t s doivent ê t r e non n u l l. 13 */ 14 p u b l i c s t a t i c f u n c t i o n gethtmldevelopped ( $employe ) { 15 $htmlcode = PersonneView : :gethtmldevelopped ( $employe ) ; 16 $htmlcode.= S a l a i r e mensuel :. $employe >g e t S a l a i r e M e n s u e l ( ). &euro ; par mois<br/>\n ; 17 $htmlcode.= Catégorie :. $employe >g e t C a t e g o r i e ( ). <br/>\n ; 18 return $htmlcode ; 19 } 20 } // end o f c l a s s EmployeView 105

107 Rémy Malgouyres, Programmation Web 21?> exemples/php2/ex16_testemploye.php 1 <?php 2 require_once ( commonfunctions. php ) ; 3 require_once ( dirname ( FILE ). / ex15_classeemployeview. php ) ; 4 require_once ( dirname ( FILE ). / ex01_classetelephone. php ) ; 5 require_once ( dirname ( FILE ). / ex02_classeadresse. php ) ; 6 require_once ( dirname ( FILE ). / ex04_classeadresseview. php ) ; 7 8 use People \ Contact \ Adresse ; 9 u s e People \ Contact \ AdresseView ; 10 use People \ Contact \ Telephone ; 11 use People \ I n d i v i d u a l s \ Personne ; 12 use People \ I n d i v i d u a l s \ PersonneView ; 13 use People \ I n d i v i d u a l s \Employees\Employe ; 14 use People \ I n d i v i d u a l s \Employees\EmployeView ; outputentetehtml5 ( Gestion d \ une exception, UTF 8, mystyle. css ) ; echo <p> ; 19 try { 20 $ a d r e s s e 1 = new Adresse ( 1 0, a l l é e du net, Quartier de l \ avenir, , Clermont Ferrand ) ; $ t e l e p h o n e s 1 = array (new Telephone ( Domicile, ) ) ; echo <strong >Construction et A f f i c h a g e d un Employé&nbsp ; :</ strong ><br/> ; 26 $employe = new Employe ( Obama, Barack, $adresse1, $telephones1, , boss ) ; 27 echo EmployeView : :gethtmldevelopped ( $employe ) ; 28 } catch ( Exception $e ) { 29 echo Exception reçue :, $e >getmessage ( ), \n ; 30 } 106

108 Chapitre 4 : Les classes en PHP echo <strong >Test avec r é c u p é r a t i o n s d e x c e p t i o n s&nbsp ; :</ strong ><br/> ; 33 try { 34 $ a d r e s s e 3 = new Adresse ( 1 0, Downing Street, null, 35 null, London, United Kingdom ) ; 36 $employe3 = new Employe ( Thatcher, Margaret, $adresse3, 37 array (new Telephone ( Emergency, 911 ) ), null, badcategory ) ; 38 echo EmployeView : :gethtmldevelopped ( $employe3 ) ; 39 } catch ( Exception $e ) { 40 echo Exception reçue :, $e >getmessage ( ), \n ; 41 } 42 echo </p> ; outputfinfichierhtml5 ( ) ; 45?> 107

109 Troisième partie Formulaires et Filtrage des Données Utilisateur 108

110 Table of Contents 5 Formulaires HTML/PHP Formulaires HTML Premier Formulaire HTML Exemple de style CSS pour formulaire Réception des données en PHP Validation pour la sécurité : Appel de filter_var Appel des vues Tableaux $_POST $_GET $_REQUEST Formulaires dynamiques an javascript Injection, Filtrage, Expressions Régulières Injections HTML et échappement Injections HTML Prévention des injections HTML par échappement Injections SQL La fonction filter_var Principe de la fonction PHP filter_var Les filtres de Validation Les filtres de Nettoyage Le filtre personnalisé FILTER_CALLBACK Expressions régulières Formulaires PHP/HTML, filtrage, exceptions La Classe Adresse Filtrage des attributs Fabrique d Adresse Génération de formulaires et classe AdresseFormView

111 TABLE OF CONTENTS 7.5 Enchaînement de la saisie à la vue Les Vues Modification d une Adresse

112 Chapitre 5 Formulaires HTML/PHP Les formulaires HTML permettent de faire saisir des données par l utilisateur via son navigateur. Ces données sont saisies dans des champs appelés inputs, qui sont définis avec la balise <input>. Les données sont ensuite récupérées dans un script, ici un script PHP. Ces données doivent impérativement être testées et filtrées pour des raisons de sécurité. 5.1 Formulaires HTML Un formulaire est créé par une balise <form> qui contient la méthode de transmission des données (GET ou POST) et l action, qui est l URL du script (ici un script PHP) qui va récupérer les données du formulaire. Chaque input a son label, qui explique à l utilisateur ce qu il doit saisir dans ce champ. La correspondance entre les inputs et le labels se fait via l attribut for du label qui doit correspondre à l attribut id de l input. L attribut name de l input servira lors de la récupération des données. Les attributs id et name de l input peuvent être égaux si on veut simplifier Premier Formulaire HTML exemples/forms1/ex01_form_html.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <t i t l e>mon premier f o r m u l a i r e HTML</ t i t l e> 6 </head> 7 <body> 8 <h1>s a i s i e d un employé</h1> 9 <form method= post action= ex02_reception. php > 10 <p> 11 <label for= nomemploye >Nom</ label> 12 <input type= t e x t name= nom id= nomemploye size= 30 /> 13 </p> 14 <p> 15 <label for= prenomemploye >Prénom</ label> 16 <input type= t e x t name= prenom id= prenomemploye size= 30 /><br/> 17 </p> 18 <p> 111

113 Rémy Malgouyres, Programmation Web 19 <label for= telephone >Téléphone</ label> 20 <input type= t e x t name= telephone id= telephone size= 15 /><br/> 21 </p> 22 <p> 23 <label for= >e mail</ label> 24 <input type= t e x t name= id= size= 20 /><br/> 25 </p> 26 <p> 27 <label for= c a t e g o r i e >Catégorie</ label> 28 <select name= c a t e g o r i e > 29 <option value= s e c r e t a i r e selected= s e l e c t e d >S e c r é t a i r e</option> 30 <option value= commercial >Commercial</ option> 31 <option value= technique >Technique</option> 32 <option value= b o s s />The Big Boss</ option> 33 </ select> 34 </p> 35 <p> 36 <input type= submit value= Envoyer ></ input> 37 </p> 38 </form> 39 </body> 40 </html> 5.2 Exemple de style CSS pour formulaire 112

114 Chapitre 5 : Formulaires HTML/PHP exemples/forms1/mystyle.css 1 2 /* s t y l e par défaut du t e x t e */ 3 body { 4 font family : Comic Sans MS ; 5 font s i z e : 18 pt ; 6 background c o l o r : #f f f ; 7 c o l o r : #222 ; 8 } 9 10 /* s t y l e du t i t r e */ 11 h1 { 12 font weight : bold ; 13 font s i z e : 150% ; 14 c o l o r : white ; 15 text a l i g n : c e n t e r ; 16 background c o l o r : #999 ; 17 padding : 15px ; 18 } /****************************************** 21 mise en forme du f o r m u l a i r e 22 \*****************************************/ /* Largeur minimale pour que l a mise en page ne c a s s e pas */ 25 form { 26 min width : 800 px ; 27 } /* tous l e s l a b e l s ont l a même l a r g e u r pour a l i g n e r l e s i nputs */ 30 form p l a b e l { 113

115 Rémy Malgouyres, Programmation Web 31 f l o a t : l e f t ; 32 width : 400px ; 33 text a l i g n : r i g h t ; 34 padding : 6px ; 35 font weight : bold ; 36 } form p input { 39 padding : 6px ; 40 margin l e f t : 20px ; 41 background c o l o r : #ddd ; 42 border s t y l e : groove ; 43 border width : 5px ; 44 border c o l o r : #444 ; 45 border r a d i u s :10px ; 46 } form p s e l e c t { 49 padding : 1px 6px ; 50 margin l e f t : 20px ; 51 background c o l o r : #ddd ; 52 border s t y l e : groove ; 53 border width : 5px ; 54 border c o l o r : #444 ; 55 border r a d i u s :10px ; 56 font s i z e : 110% ; 57 } /* input s p é c i a l pour l e boutton submit */ 60 form p input. sanslabel { 61 margin l e f t : 432px ; /* : a l i g n é sur l e s a u t r e s i nputs */ 62 font s i z e : 130% ; 63 font weight : bolder ; 64 background c o l o r :#f f ; 65 c o l o r :white ; 66 } form p { 69 background c o l o r : #f f f ; 70 padding : 0px ; 71 } form p span. errormsg { 74 c o l o r :red ; 75 font weight :bolder ; 76 } /****************************************/ /* s t y l e par défaut des l i e n s */ 82 a : l i n k { 83 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 84 c o l o r : #00e ; 85 }

116 Chapitre 5 : Formulaires HTML/PHP 87 /* s t y l e des l i e n s v i s i t é s */ 88 a : v i s i t e d { 89 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 90 c o l o r : #00c ;/* bleu c l a i r */ 91 } /* s t y l e des l i e n s v i s i t é s */ 94 a :hover { 95 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 96 c o l o r : #e40 ;/* rouge v i f */ 97 } /* s t y l e des éléments importants */ 100 strong { 101 font v a r i a n t : small caps ; 102 font weight : bolder ; 103 c o l o r : black ; 104 } /* s t y l e des éléments mis en évidence */ 107 em { 108 font s t y l e : i t a l i c ; 109 c o l o r : black ; 110 } p { 113 background c o l o r : #ddd ; 114 text a l i g n : j u s t i f y ; 115 padding : 5 pt ; 116 } exemples/forms1/mystyle.css 1 2 /* s t y l e par défaut du t e x t e */ 3 body { 4 font family : Comic Sans MS ; 5 font s i z e : 18 pt ; 6 background c o l o r : #f f f ; 7 c o l o r : #222 ; 8 } 9 10 /* s t y l e du t i t r e */ 11 h1 { 12 font weight : bold ; 13 font s i z e : 150% ; 14 c o l o r : white ; 15 text a l i g n : c e n t e r ; 16 background c o l o r : #999 ; 17 padding : 15px ; 18 } /****************************************** 21 mise en forme du f o r m u l a i r e 22 \*****************************************/

117 Rémy Malgouyres, Programmation Web 24 /* Largeur minimale pour que l a mise en page ne c a s s e pas */ 25 form { 26 min width : 800 px ; 27 } /* tous l e s l a b e l s ont l a même l a r g e u r pour a l i g n e r l e s i nputs */ 30 form p l a b e l { 31 f l o a t : l e f t ; 32 width : 400px ; 33 text a l i g n : r i g h t ; 34 padding : 6px ; 35 font weight : bold ; 36 } form p input { 39 padding : 6px ; 40 margin l e f t : 20px ; 41 background c o l o r : #ddd ; 42 border s t y l e : groove ; 43 border width : 5px ; 44 border c o l o r : #444 ; 45 border r a d i u s :10px ; 46 } form p s e l e c t { 49 padding : 1px 6px ; 50 margin l e f t : 20px ; 51 background c o l o r : #ddd ; 52 border s t y l e : groove ; 53 border width : 5px ; 54 border c o l o r : #444 ; 55 border r a d i u s :10px ; 56 font s i z e : 110% ; 57 } /* input s p é c i a l pour l e boutton submit */ 60 form p input. sanslabel { 61 margin l e f t : 432px ; /* : a l i g n é sur l e s a u t r e s i nputs */ 62 font s i z e : 130% ; 63 font weight : bolder ; 64 background c o l o r :#f f ; 65 c o l o r :white ; 66 } form p { 69 background c o l o r : #f f f ; 70 padding : 0px ; 71 } form p span. errormsg { 74 c o l o r :red ; 75 font weight :bolder ; 76 } /****************************************/

118 Chapitre 5 : Formulaires HTML/PHP /* s t y l e par défaut des l i e n s */ 82 a : l i n k { 83 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 84 c o l o r : #00e ; 85 } /* s t y l e des l i e n s v i s i t é s */ 88 a : v i s i t e d { 89 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 90 c o l o r : #00c ;/* bleu c l a i r */ 91 } /* s t y l e des l i e n s v i s i t é s */ 94 a :hover { 95 text d e c o r a t i o n : u n d e r l i n e ; /* s o u l i g n é */ 96 c o l o r : #e40 ;/* rouge v i f */ 97 } /* s t y l e des éléments importants */ 100 strong { 101 font v a r i a n t : small caps ; 102 font weight : bolder ; 103 c o l o r : black ; 104 } /* s t y l e des éléments mis en évidence */ 107 em { 108 font s t y l e : i t a l i c ; 109 c o l o r : black ; 110 } p { 113 background c o l o r : #ddd ; 114 text a l i g n : j u s t i f y ; 115 padding : 5 pt ; 116 } Réception des données en PHP La réception des données se fait ici par la méthode POST (comme indiqué dans la balise <form>). Les données sont récupérées dans un tableau associatif $_POST, dont les clefs sont les attributs name des inputs du formulaire précédent. On teste si ces attributs existent bien via la fonction isset. exemples/forms1/ex02_reception.php 1 <?php 2 $nom = i s s e t ($_POST[ nom ] )? $_POST[ nom ] : ; 3 $prenom = i s s e t ($_POST[ prenom ] )? $_POST[ prenom ] : ; 4 $telephone = i s s e t ($_POST[ telephone ] )? $_POST[ telephone ] : ; 5 $ = i s s e t ($_POST[ ] )? $_POST[ ] : ; 6 $ c a t e g o r i e = i s s e t ($_POST[ c a t e g o r i e ] )? $_POST[ c a t e g o r i e ] : ; 7 8 r e q u i r e ( ex04_validation. php ) ; 117

119 Rémy Malgouyres, Programmation Web 9 10 i f ( empty ( $dataerrors ) ) { 11 r e q u i r e ( ex05_vuesuccess. php ) ; 12 } e l s e { 13 r e q u i r e ( ex06_vueerror. php ) ; 14 } 15?> 5.3 Validation pour la sécurité : Appel de filter_var Pour des raisons de sécurité (voir le chpitre 6), un filtrage systématique doit être effectué sur les données reçus dans les tableaux $_GET, $_POST, $_COOCKIE, etc. Pour cela, on fait généralement un script de validation qui valide ou nettoie les données, par exemple en utilisant la fonction filter_var. exemples/forms1/ex04_validation.php 1 <?php 2 require_once ( e x 0 3 _ v a l i d U t i l s. php ) ; 3 4 $dataerrors = array ( ) ; 5 6 // v a l i d a t i o n du nom 7 $nom = f i l t e r _ v a r ($nom, g e t S a n i t i z e F i l t e r ( string ) ) ; 8 9 // v a l i d a t i o n du prénom 10 $prenom = f i l t e r _ v a r ( $prenom, g e t S a n i t i z e F i l t e r ( string ) ) ; // v a l i d a t i o n du téléphone 13 $telephone = f i l t e r _ v a r ( $telephone, g e t S a n i t i z e F i l t e r ( string ) ) ; // v a l i d a t i o n de l a d r e s s e e mail i f ( f i l t e r _ v a r ( $ , g e t V a l i d a t e F i l t e r ( ) )===f a l s e ) { 18 $dataerrors [ ] = Erreur : l a d r e s s e e mail e s t i n v a l i d e. ; 19 } // v a l i d a t i o n de l a c a t é g o r i e 22 $ c a t e g o r i e = f i l t e r _ v a r ( $ c a t e g o r i e, g e t S a n i t i z e F i l t e r ( string ) ) ; 23?> exemples/forms1/ex03_validutils.php 1 <?php 2 // Méthode retournant l e f i l t r e de v a l i d a t i o n à u t i l i s e r 3 // dans l a f o n c t i o n f i l t e r _ v a r 4 f u n c t i o n g e t V a l i d a t e F i l t e r ( $type ) 5 { 6 switch ( $type ) { 7 case 8 $ f i l t e r = FILTER_VALIDATE_ ; 9 break ; 10 case i n t : 11 $ f i l t e r = FILTER_VALIDATE_INT; 118

120 Chapitre 5 : Formulaires HTML/PHP 12 break ; 13 case boolean : 14 $ f i l t e r = FILTER_VALIDATE_BOOLEAN; 15 break ; 16 case ip : 17 $ f i l t e r = FILTER_VALIDATE_IP; 18 break ; 19 case u r l : 20 $ f i l t e r = FILTER_VALIDATE_URL; 21 break ; 22 d e f a u l t : // important!!! 23 $ f i l t e r = f a l s e ; // Si type e s t faux, l a v a l i d. échoue. 24 } 25 return $ f i l t e r ; 26 } // Méthode retournant l e f i l t r e de nettoyage à u t i l i s e r 29 // dans l a f o n c t i o n f i l t e r _ v a r 30 f u n c t i o n g e t S a n i t i z e F i l t e r ( $type ) 31 { 32 switch ( $type ) { 33 case s t r i n g : 34 $ f i l t e r = FILTER_SANITIZE_STRING ; 35 break ; 36 case t e x t : 37 $ f i l t e r = FILTER_SANITIZE_FULL_SPECIAL_CHARS; 38 break ; 39 case u r l : 40 $ f i l t e r = FILTER_SANITIZE_URL ; 41 break ; 42 d e f a u l t : // important!!! 43 $ f i l t e r = f a l s e ; // Si type e s t faux, l a v a l i d. échoue. 44 } 45 return $ f i l t e r ; 46 } 47 48?> 5.4 Appel des vues Comme nous l avons vu dans la partie 5.2.1, un test permet, à la suite dee la validation, de savoir si une erreur s est produite. Suivant le cas, La vue normale affiche les données saisies ; Une vue d erreurs affiche les messages d erreur. exemples/forms1/ex05_vuesuccess.php 1 <?php 2 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 3 4 outputentetehtml5 ( A f f i c h a g e des données s a i s i e s, UTF 8, mystyle. css ) ; 5 119

121 Rémy Malgouyres, Programmation Web 6 echo <h1>données reçues </h1>\n ; 7 echo <p>\n ; 8 echo nom :. $nom. <br/>\n ; 9 echo prenom :. $prenom. <br/>\n ; 10 echo Téléphone :. $telephone. <br/>\n ; 11 echo E mail :. $ . <br/>\n ; 12 echo Catégorie :. $ c a t e g o r i e. <br/>\n ; 13 echo </p>\n ; outputfinfichierhtml5 ( ) ; 16 17?> exemples/forms1/ex06_vueerror.php 1 <?php 2 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 3 outputentetehtml5 ( Erreurs données s a i s i e s, UTF 8, mystyle. css ) ; 4 5 echo <h1>données r e ç u e s i n c o r r e c t e s </h1>\n ; 6 7 echo <ul> ; 8 f o r e a c h ( $dataerrors as $ f i e l d => $message ) { 9 echo < l i>problème avec l \ a t t r i b u t <code>. $ f i e l d 10. </code>. <span style= c o l o r : red ; >. $message. </span></ l i> ; 11 } 120

122 Chapitre 5 : Formulaires HTML/PHP 12 echo </ul> ; echo <p>merci de bien v o u l o i r <a href= ex01_form_html. html >Essayer à nouveau </a></p> ; outputfinfichierhtml5 ( ) ; 17?> Dans tous les cas, seuls les scripts implémentant des vues envoie du code HTML sur la sortie standard. 5.5 Tableaux $_POST $_GET $_REQUEST Nous avons vu, pour le moment, deux méthodes pour transmettre des données d un script PHP à l autre : la méthode GET et la méthode POST. On réceptionne alors les données (respectivement) dans des tableaux associatifs $_POST $_GET. On peut aussi utiliser un tableau associatif $_REQUEST, qui contient à la fois les éléments du tableau $_POST et les éléments du tableau $_GET. Remarque : le tableau $_REQUEST contient aussi les éléments du tableau $_COOKIE. exemples/forms1/ex07_get_vs_posthidden.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>transmission de Paramètres</ t i t l e> 7 </head> 121

123 Rémy Malgouyres, Programmation Web 8 <body> 9 <h1>transmission de Paramètres<br/>(<i>POST v e r s u s GET</ i>)</h1> 10 <! Ce f o r m u l a i r e transmet t r o i s v a l e u r s non s a i s i e s par l u t i l i s a t e u r > 11 <form method= post action= ex08_get_post_request_param. php?language=f r&r e g i o n =eu > 12 <input type= hidden name= referredfrom value= searchengine > 13 <p> 14 <label for= prenomemploye >Prénom</ label> 15 <input type= t e x t name= prenom id= prenomemploye size= 30 /><br/> 16 </p> 17 <p> 18 <input type= submit value= Envoyer class= sanslabel ></input> 19 </p> 20 </form> 21 </body> 22 </html> exemples/forms1/ex08_get_post_request_param.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>transmission de Paramètres</ t i t l e> 7 </head> 8 <body> 9 <h1>réception de paramètres<br/>(<code>$_post</code>, <code>$_get</code> et < code>$_request</code>)</h1> 10 <?php 11 f o r e a c h ($_GET as $key => $val ) { 12 echo h t m l e n t i t i e s ( \$_GET[. $key. ] =. $val, ENT_COMPAT, UTF 8 ). <br /> ; 13 } 14 f o r e a c h ($_POST as $key => $val ) { 15 echo h t m l e n t i t i e s ( \$_POST[. $key. ] =. $val, ENT_COMPAT, UTF 8 ). <br /> ; ; 16 } 17 f o r e a c h ($_REQUEST as $key => $val ) { 122

124 Chapitre 5 : Formulaires HTML/PHP 18 echo h t m l e n t i t i e s ( \$_REQUEST[. $key. ] =. $val, ENT_COMPAT, UTF 8 ). <br/> ; ; 19 } 20?> 21 </body> 22 </html> 5.6 Formulaires dynamiques an javascript Nous voyons ici un exemple d utilisation du Javascript pour créer un formulaire dont les attributs dépendent de la valeur d un premier champ. Lorsqu on sélectionne deuxième année, un nouveau champ apparaît. Pour celà, on utilise l événement onchange sur l input de l année, qui est géré par la fonction anneechange. On teste alors la valeur de l attribut, puis le cas échéant on génère un nouveau champ dans un div d id attributsupplementaire. Pour plus d information sur les pages web dynamiques en Javascript, voir le cours correspondant sur 123

125 Rémy Malgouyres, Programmation Web exemples/javascript/formulaire_dynamique.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <t i t l e>formulaire dynamique</ t i t l e> 6 </head> 7 <body> 8 <form method= post action= r e c e p t i o n. php > 9 <p> 10 <l a b e l for= nom >Nom</ l a b e l><input name= nom id= nom /> 11 </p> 12 <p> 13 <select name= annee id= annee pattern= ( premiere ) ( deuxieme ) onchange= anneechange ( ) ; > 14 <option value= c h o i s i s s e z selected disabled> c h o i s i s s e z </option> 15 <option value= premiere >Première année</option> 16 <option value= deuxième >Deuxième année</ option> 17 </ select> 18 </p> 19 <div id= a t t r i b u t S u p p l e m e n t a i r e > </ div> 22 <p> 23 <input type= submit value= OK /> 24 </p> 25 </form> 26 <script> 27 f u n c t i o n anneechange ( ) { 28 var paragraphe = document. getelementbyid ( a t t r i b u t S u p p l e m e n t a i r e ) ; 29 paragraphe. innerhtml=document. getelementbyid ( annee ). value+ année. ; 30 i f ( document. getelementbyid ( annee ). value == deuxième ) { 31 paragraphe. innerhtml+= <l a b e l >O r i e n t a t i o n prévue pour l année prochaine :</l a b e l > 32 + <select name= o r i e n t a t i o n id= o r i e n t a t i o n > 33 + <option value= LP >LP</ option> 34 + <option value= master >master</ option> 35 + <option value=\ inge \ >Ecole d ingé </option> 36 + <option value= boulot >Boulot</option> 37 + <option value= autre >Autre</option> 38 + </ select> ; } 124

126 Chapitre 5 : Formulaires HTML/PHP 41 } 42 anneechange ( ) ; 43 </ script> 44 </body> 45 </html> exemples/javascript/reception.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <t i t l e>formulaire dynamique</ t i t l e> 6 </head> 7 <body> 8 <?php 9 $nom= ( i s s e t ($_POST[ nom ] ) )? $_POST[ nom ] : nom indéterminé ; 10 $annee = ( i s s e t ($_POST[ annee ] ) )? $_POST[ annee ] : année indéteminée ; 11 echo Nom :. $nom. <br/> ; 12 echo Année :. $annee. <br/> ; 13 i f ( $annee== deuxième ) 14 echo O r i e n t a t i o n :.$_POST[ o r i e n t a t i o n ] ; ?> 18 </body> 19 </html> 125

127 Chapitre 6 Injection, Filtrage, Expressions Régulières 6.1 Injections HTML et échappement Injections HTML Les injections XSS sont un moyen pour un pirate d exécuter du code non prévu en exploitant les interfaces entre PHP et d autres langages (HTML, Javascript, SQL, etc...). Pour celà, le pirate rentre dans un input du code, qui n est pas détecté par PHP (on a simplement une chaîne de caractères au niveau de PHP), mais qui est interprété par un autre langage interfacé avec PHP. Voyons un exemple d injection HTML. L utilisateur malveillant va entrer dans un textarea, de nom desctiption, du code HTML pour introduire dans le site victime un lien vers un site pirate. Si l utilisateur inaverti ou distrait clique sur ce lien, le pirate peut alors demander à l utilisateur de rentrer ses identifiants (usurpation d identité) ou ses données de carte bancaire (escroquerie), etc. Voyons tout d abord de formulaire et sa réception dans le cadre de son utilisation normale. Figure 6.1 : Un gentil formulaire 126

128 Chapitre 6 : Injection, Filtrage, Expressions Régulières Figure 6.2 : Le site affiche en HTML les données saisies dans le gentil formulaire Le code source du formulaire et de sa réception est le suivant : exemples/filtrage/ex00_1_postparamforhtml_inject.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>post un Nom</ t i t l e> 7 </head> 8 <body> 9 <h1>post d une chaîne</h1> 10 <form method= p o s t action= ex00_2_receptparamforhtml_inject. php > 11 <label for= d e s c r i p t i o n style= margin r i g h t : 10px ; v e r t i c a l a l i g n :top ; > D e s c r i p t i o n :</ label> 12 <textarea name= d e s c r i p t i o n id= d e s c r i p t i o n cols= 50 row= 6 style= v e r t i c a l a l i g n :top ; > 13 </ textarea> 14 <input type= submit value= Envoyer /> 15 </form> 16 </body> 17 </html> exemples/filtrage/ex00_2_receptparamforhtml_inject.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /><link rel= s t y l e s h e e t href=. / mystyle. c s s /> 5 <t i t l e>réception Vulnérable à I n j e c t i o n s XSS</ t i t l e> 6 </head> 7 <body> 8 <h1>réception Vulnérable à I n j e c t i o n s <i>xss</ i></h1> 9 <p> 10 <strong>la D e s c r i p t i o n du c l i e n t e s t&nbsp ; :</strong><br/> 11 <?php 127

129 Rémy Malgouyres, Programmation Web 12 i f ( i s s e t ($_POST[ d e s c r i p t i o n ] ) ) { 13 echo $_POST[ d e s c r i p t i o n ] ; 14 } 15?> 16 <br/>ceci e s t l a s u i t e du document. 17 </p> 18 </body> 19 </html> Le pirate entre alors dans un input du code HTML : Figure 6.3 : Injection HTML ajoutant un lien au site Le résultat est l apparition d un lien non prévu sur le site : Figure 6.4 : L affichage des données du formulaire sort le code HTML entré par le pirate Prévention des injections HTML par échappement a Échappement par htmlentities Différents outils de filtrage sont disponibles en PHP. Le plus simple pour la sécurité consiste à utiliser la méthode htmlentities qui tranforme dans une chaîne tous les caractères spéciaux en leurs entités HTML (code spécial pour afficher un caractère en HTML). 128

130 Chapitre 6 : Injection, Filtrage, Expressions Régulières Il faut cependant prendre garde que si l utilisateur ne rentre pas les caratères en entrée avec le même encodage que celui utilisé par PHP en sortie, les caractères spéciaux n ont pas le même code et la fonction htmlentities ne fonctionnera pas bien, laissant la porte ouverte à des attaques. On peut spécifier l encoding de sortie de htmlentities dans son troisième paramètre. Dans l exemple d injection HTML ajoutant un lien ci-dessus, on obtiendrait lors de l affichage : Figure 6.5 : Un gentil formulaire Le code HTML produit par le CGI est le suivant : exemples/filtrage/ex00_5_htmlentitieshtml_output.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /><link rel= s t y l e s h e e t href=. / mystyle. c s s /> 5 <t i t l e>réception avec échappement</ t i t l e> 6 </head> 7 <body> 8 <h1>réception avec échappement par <code>h t m l e n t i t i e s</code></h1> 9 <p> 10 Le nom du c l i e n t e s t&nbsp ; : 11 Ceci e s t une d e s c r i p t i o n innocente. 12 &l t ; span s t y l e=&quot ; p o s i t i o n : r e l a t i v e ; r i g h t :50px ; top :70px ;&quot ;&gt ; 13 Pour payer avec une CB 14 &l t ; a h r e f=http :// s i t e P i r a t e. com&gt ; Cliquez i c i&l t ; / a&gt ; 15 &l t ; / span&gt ; <br/>ceci e s t l a s u i t e du document. 16 </p> 17 </body> 18 </html> Ça n est pas très joli mais c est inoffensif sauf si l utilisateur fait vraiment exprès de copier l adresse du lien dans sa barre d adresse. Pour éviter complètement l apparition de code, HTML ou autre, ou plus généralement de données non conforme à un format attendu, nous veroons plus loin comment utiliser des expressions régulières b Options d échappement Nous voyons ici trois exemples d échappement qui traitent différemment les guillemets et les apostrophes (doubles et simples quotes). Les chaines positées sont les suivantes : 129

131 Rémy Malgouyres, Programmation Web exemples/filtrage/ex02_postparam.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>post de deux c h a î n e s</ t i t l e> 7 </head> 8 <body> 9 <h1>post de deux c h a î n e s</h1> 10 <form method= p o s t action= ex03_ escapetestrequest. php > 11 <input type= hidden name= chaine1 value= Ceci e s t l exemple de chaîne avec apostrophe /> 12 <input type= hidden name= chaine2 value= Ceci e s t s o i t d i s a n t un &quot ; autre&quot ; exemple. /> 13 <input type= submit value= Envoyer class= sanslabel /> 14 </form> 15 </body> 16 </html> À la réception, on observe la chose suivante suivant les options données en paramètre de htmlentities : exemples/filtrage/ex03_escapetestrequest.php 1 <?php r e q u i r e (. / commonfunctions. php ) ; 2 3 outputentetehtml5 ( Réception et échappement HTML, UTF 8, mystyle. css ) ; 4 5 echo <h1>réception et échappement <i >HTML</i ></h1> ; 6 7 $chaine1 = $_REQUEST[ chaine1 ] ; 8 $chaine2 = $_REQUEST[ chaine2 ] ; 9 130

132 Chapitre 6 : Injection, Filtrage, Expressions Régulières 10 echo <p>\n ; 11 echo Apostrophe avec a d d s l a s h e s :. a d d s l a s h e s ( $chaine1 ). <br>\n ; 12 echo Guillemets avec a d d s l a s h e s :. a d d s l a s h e s ( $chaine2 ). <br>\n ; 13 echo </p>\n ; echo <p>\n ; 16 echo Apostrophe avec h t m l e n t i t i e s et ENT_COMPAT :. h t m l e n t i t i e s ( $chaine1, ENT_COMPAT, UTF 8, f a l s e ). <br>\n ; 17 echo Guillemets avec a d d s l a s h e s ENT_COMPAT :. h t m l e n t i t i e s ( $chaine2, ENT_COMPAT, UTF 8, f a l s e ). <br>\n ; 18 echo </p>\n ; echo <p>\n ; 21 echo Apostrophe avec h t m l e n t i t i e s et ENT_QUOTES :. h t m l e n t i t i e s ( $chaine1, ENT_QUOTES, UTF 8, f a l s e ). <br>\n ; 22 echo Guillemets avec a d d s l a s h e s ENT_QUOTES :. h t m l e n t i t i e s ( $chaine2, ENT_QUOTES, UTF 8, f a l s e ). <br>\n ; 23 echo </p>\n ; echo <p>\n ; 26 echo Apostrophe avec h t m l e n t i t i e s et ENT_NOQUOTES :. h t m l e n t i t i e s ( $chaine1, ENT_NOQUOTES, UTF 8, f a l s e ). <br>\n ; 27 echo Guillemets avec a d d s l a s h e s ENT_NOQUOTES :. h t m l e n t i t i e s ( $chaine2, ENT_NOQUOTES, UTF 8, f a l s e ). <br>\n ; 28 echo </p> ; 29 30?> 31 <form method= p o s t action= ex03_ escapetestrequest. php > 32 <input type= t e x t name= chaine1 value= <?php echo $chaine1 ;?> > 33 <input type= t e x t name= chaine2 value= <?php echo $chaine2 ;?> > 34 <input type= submit value= Envoyer class= sanslabel ></input> 35 </form> 36 <?php 37 outputfinfichierhtml5 ( ) ; 38?> Le code source HTML généré par le CGI est le suivant : exemples/filtrage/ex03_escapetestrequest_php_htmloutput.html 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href= mystyle. c s s /> 6 <t i t l e>réception et échappement HTML</ t i t l e> 7 </head> 8 <body> 9 <h1>réception et échappement <i>html</ i></h1><p> 10 Apostrophe avec a d d s l a s h e s : Ceci e s t l \ exemple de chaîne avec apostrophe<br> 11 Guillemets avec a d d s l a s h e s : Ceci e s t s o i t d i s a n t un \ autre \ exemple.<br> 12 </p> 13 <p> 14 Apostrophe avec h t m l e n t i t i e s et ENT_COMPAT : Ceci e s t l exemple de cha&i c i r c ; ne avec apostrophe<br> 15 Guillemets avec a d d s l a s h e s ENT_COMPAT : Ceci e s t s o i t d i s a n t un &quot ; autre&quot ; exemple.<br> 131

133 Rémy Malgouyres, Programmation Web 16 </p> 17 <p> 18 Apostrophe avec h t m l e n t i t i e s et ENT_QUOTES : Ceci e s t l &#039 ;exemple de cha& i c i r c ; ne avec apostrophe<br> 19 Guillemets avec a d d s l a s h e s ENT_QUOTES : Ceci e s t s o i t d i s a n t un &quot ; autre&quot ; exemple.<br> 20 </p> 21 <p> 22 Apostrophe avec h t m l e n t i t i e s et ENT_NOQUOTES : Ceci e s t l exemple de cha&i c i r c ; ne avec apostrophe<br> 23 Guillemets avec a d d s l a s h e s ENT_NOQUOTES : Ceci e s t s o i t d i s a n t un autre exemple.<br> 24 </p> <form method= p o s t action= ex03_ escapetestrequest. php > 25 <input type= t e x t name= chaine1 value= Ceci e s t l exemple de chaîne avec apostrophe > 26 <input type= t e x t name= chaine2 value= Ceci e s t s o i t d i s a n t un autre exemple. > 27 <input type= submit value= Envoyer class= sanslabel ></input> 28 </form> 29 </body> 30 </html> c Inverser l échappement Après un échappement à réception des données, on peut inverser cet échappement pour restaurer les données bruttes d origine, par exemple pour renvoyer ces données dans les inputs d un formulaire : exemples/filtrage/ex05_htmlentitiesent_quotes_forminput.php 132

134 Chapitre 6 : Injection, Filtrage, Expressions Régulières 1 <?php r e q u i r e (. / commonfunctions. php ) ; 2 3 outputentetehtml5 ( html_entity_decode, UTF 8, mystyle. css ) ; 4 5 echo <h1>annuler l échappement avec <code>html_ entity_ decode </code ></h1> ; 6 7 $chaine1 = h t m l e n t i t i e s ($_REQUEST[ chaine1 ], ENT_QUOTES, UTF 8, f a l s e ) ; 8 $chaine2 = h t m l e n t i t i e s ($_REQUEST[ chaine2 ], ENT_QUOTES, UTF 8, f a l s e ) ; 9 10 echo <p s t y l e =\ font size :80% ;\ >\n ; 11 echo $chaine1. <br/>( codée avec. h t m l e n t i t i e s ( h t m l e n t i t i e s (\$_REQUEST[ chaine1 ], ENT_QUOTES, UTF 8, f a l s e ), ENT_QUOTES, UTF 8, f a l s e ). )<br >\n ; 12 echo $chaine2. <br/>( codée avec. h t m l e n t i t i e s ( h t m l e n t i t i e s (\$_REQUEST[ chaine2 ], ENT_QUOTES, UTF 8, f a l s e ), ENT_QUOTES, UTF 8, f a l s e ). )<br >\n ; 13 echo </p>pour r e p o s t e r l e s c h a î n e s dans un f o r m u l a i r e, on \ décode l échappement\ <br/>\n ; 14?> 15 <form method= p o s t action= ex05_htmlentitiesent_quotes_forminput. php > 16 <input style= font s i z e :100% ; type= t e x t name= chaine1 value= <?php echo $chaine1 ;?> size= 30 /> 17 <input style= font s i z e :100% ; type= t e x t name= chaine2 value= <?php echo $chaine2 ;?> size= 30 /> 18 <input type= submit value= Envoyer class= sanslabel /> 19 </form> 20 <?php 21 echo <p>\n ; 22 echo html_entity_decode ( $chaine1, ENT_QUOTES, UTF 8 ). <br>\n ; 23 echo html_entity_decode ( $chaine2, ENT_QUOTES, UTF 8 ). <br>\n ; 24 echo </p>\n ; outputfinfichierhtml5 ( ) ; 27?> 6.2 Injections SQL Une injection SQL consiste à entre dans les inputs utilisateur du code SQL. Ces attaques sont particulièrement dansgereuses car elles peuvent etre exploitées par un pirtae pour : Accéder à des données confidentielles, par exemple à toutes les données de la base ; Détruire ou altérer des données, par exemple supprimer la totalité d une table. Voici un exemple de code qui insère une donnée (colonne chaine) de type chaine (varchar) dans une table Table1. exemples/filtrage/ex06_0_postparamfordb.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 133

135 Rémy Malgouyres, Programmation Web 6 <t i t l e>f o r m i l a i r e HTML</ t i t l e> 7 </head> 8 <body> 9 <h1>s a i s i e d une Chaîne</h1> 10 <! Ce f o r m u l a i r e transmet t r o i s v a l e u r s non s a i s i e s par l u t i l i s a t e u r > 11 <form method= p o s t action= ex07_ exinjectmysql. php > 12 <label for= chaine1 >Entrez une chaîne</ label> 13 <input type= t e x t e id= chaine1 name= chaine1 size= 45 /><br/> <input type= submit value= Envoyer class= sanslabel ></input> 16 </form> 17 </body> 18 </html> exemples/filtrage/ex07_exinjectmysql.php 1 2 <?php 3 i n c l u d e (. / commonfunctions. php ) ; 4 outputentetehtml5 ( Exemple d \ i n j e c t i o n SQL, UTF 8, mystyle. css ) ; 5 6 echo <h1>réception v u l n é r a b l e à une i n j e c t i o n </h1> ; 7 8 // On se connecte au s e r v e u r de bases de données. 9 // Adapter l e nom d hote où se trouve l e s e r v e u r mysql 10 // mysqli ( $sql_server_url, $sql_user, $sql_user_password, $database_name ) 11 $mysqli = new mysqli ( progweb, t e s t U s e r, motdepasse, basetest ) ; // V é r i f i c a t i o n de l a connexion : 14 i f ( mysqli_connect_errno ( ) ) { 15 p r i n t f ( Échec de l a connexion : %s \n, mysqli_connect_error ( ) ) ; 16 e x i t ( ) ; 17 } 18 echo Connecté au s e r v e u r de bases de données mysql.<br/> ; $chaine1= ; 21 i f ( i s s e t ($_POST[ chaine1 ] ) ) { 22 $chaine1 = $_POST[ chaine1 ] ; 23 } 24 echo Chaîne e n t r é e par l u t i l i s a t e u r : <code>. $chaine1. </code><br/> ; // I n s e r t i o n de l a chaîne dans l a t a b l e Table1 ( r e q u ê t e SQL) : 27 $requete = INSERT INTO Table1 ( chaine ) VALUES (. $chaine1. ) ; echo Requête exécutée :<br/><code>. $requete. </code><br/> ; $ r e s u l t = $mysqli >multi_query ( $requete ) or d i e ( Query f a i l e d :. mysql_error ( ). <br/> ) ; // On ferme l a connection 34 $mysqli >c l o s e ( ) ; outputfinfichierhtml5 ( ) ; 37?> 134

136 Chapitre 6 : Injection, Filtrage, Expressions Régulières Voici deux exemple d injections exploitant l absence de filtrage dans ce code. Le premier exemple, gentillet, consiste juste à insérer deux données au lieu d une dans la table : Figure 6.6 : L état des données avant l injection SQL par le pirate Figure 6.7 : Données saisies par le pirate pour l injection SQL Le deuxième exemple, plus méchant, consiste pour le pirate à supprimer toutes les données contenues dans la table : exemples/filtrage/ex09_mysqlescapestring.php 1 2 <?php 3 i n c l u d e (. / commonfunctions. php ) ; 4 outputentetehtml5 ( Echappement mysqli : :real_escape_string, UTF 8, mystyle. css ) ; 5 6 echo <h1>réception avec échappement <code>mysqli : :real_escape_string </code></ h1> ; 7 8 // On se connecte au s e r v e u r de bases de données. 9 // Adapter l e nom d hote où se trouve l e s e r v e u r mysql 10 // mysqli ( $sql_server_url, $sql_user, $sql_user_password, $database_name ) 11 $mysqli = new mysqli ( progweb, t e s t U s e r, motdepasse, basetest ) ; // V é r i f i c a t i o n de l a connexion : 135

137 Rémy Malgouyres, Programmation Web Figure 6.8 : Requête exécutée lors de l injection SQL Figure 6.9 : L état des données après l injection SQL par le pirate Figure 6.10 : Données saisies par le pirate pour l injection SQL Figure 6.11 : Requête exécutée lors de l injection SQL 136

138 Chapitre 6 : Injection, Filtrage, Expressions Régulières Figure 6.12 : L état des données près l injection SQL par le pirate 14 i f ( mysqli_connect_errno ( ) ) { 15 p r i n t f ( Échec de l a connexion : %s \n, mysqli_connect_error ( ) ) ; 16 e x i t ( ) ; 17 } 18 echo Connecté au s e r v e u r de bases de données mysql.<br/> ; $chaine1= ; 21 i f ( i s s e t ($_POST[ chaine1 ] ) ) { 22 $chaine1 = $mysqli >r e a l _ e s c a p e _ s t r i n g ($_POST[ chaine1 ] ) ; 23 } 24 echo Chaîne e n t r é e par l u t i l i s a t e u r : <code>.$_post[ chaine1 ]. </code><br /> ; 25 echo Chaîne e n t r é e par l u t i l i s a t e u r échapée : <code>. $chaine1. </code><br/> ; // I n s e r t i o n de l a chaîne dans l a t a b l e Table1 ( r e q u ê t e SQL) : 28 $requete = INSERT INTO Table1 ( chaine ) VALUES (. $chaine1. ) ; echo Requête exécutée :<br/><code>. $requete. </code><br/> ; $ r e s u l t = $mysqli >multi_query ( $requete ) or d i e ( Query f a i l e d :. mysql_error ( ). <br/> ) ; // On ferme l a connection 137

139 Rémy Malgouyres, Programmation Web 35 $mysqli >c l o s e ( ) ; outputfinfichierhtml5 ( ) ; 38?> Figure 6.13 : Données dans la base après tentative d injection SQL avec échappement exemples/filtrage/ex11_mysqlescapestringoutput.php 1 2 <?php 3 i n c l u d e (. / commonfunctions. php ) ; 4 outputentetehtml5 ( En s o r t i e de BD, UTF 8, mystyle. css ) ; 5 6 echo <h1>a p p l i c a t i o n d <code>h t m l e n t i t i e s </code><br/>en s o r t i e de BD</h1> ; 7 8 // On se connecte au s e r v e u r de bases de données. 9 // Adapter l e nom d hote où se trouve l e s e r v e u r mysql 10 // mysqli ( $sql_server_url, $sql_user, $sql_user_password, $database_name ) 11 $mysqli = new mysqli ( progweb, t e s t U s e r, motdepasse, basetest ) ; // V é r i f i c a t i o n de l a connexion : 138

140 Chapitre 6 : Injection, Filtrage, Expressions Régulières 14 i f ( mysqli_connect_errno ( ) ) { 15 p r i n t f ( Échec de l a connexion : %s \n, mysqli_connect_error ( ) ) ; 16 e x i t ( ) ; 17 } 18 echo Connecté au s e r v e u r de bases de données mysql.<br/> ; // I n s e r t i o n de l a chaîne dans l a t a b l e Table1 ( r e q u ê t e SQL) : 21 $requete = SELECT * FROM Table1 ; $ r e s u l t = $mysqli >query ( $requete ) or d i e ( Query f a i l e d :. mysql_error ( ). < br/> ) ; while ( $ligneresreq = mysqli_fetch_array ( $ r e s u l t, MYSQL_ASSOC) ) { 26 echo Donnée s o r t i e de l a t a b l e :<br/><code>. h t m l e n t i t i e s ( $ligneresreq [ chaine ], ENT_QUOTES, UTF 8 ). </code><br/> ; 27 } 28 // On ferme l a connection 29 $mysqli >c l o s e ( ) ; outputfinfichierhtml5 ( ) ; 32?> 6.3 La fonction filter_var Principe de la fonction PHP filter_var La fonction PHP filter_var permet 1. de valider la forme d une chaine de caractères attendue suivant son usage (exemple : adresse e mail, URL, nombre réel, adresse IP, etc.). 2. de nettoyer une chaine de caractères attendue suivant son usage (élimination des caractères inattendus compte tenu du type de données (exemple : élimination d un caractère dans un nombre entier). le prototype de la fonction filter_var est : mixed filter_var(mixed $variable, int $filter = FILTER_DEFAULT, mixed $options) La fonction retourne false en cas de données invalides avec échec du filtre, ou les données elles mêmes dans le cas de données valides, ou encore les données filtrées en cas de filtres de nettoyage. $variable est la valeur à filtrer ; $filter est le type de filtre. Bien qu il soit en option et qu il est une valeur par défaut définie dans la configuration du serveur (fichier php.ini), il est fortement conseillé de spécifier un, ou plusieurs, filtres) $options définit les options et/ou les flags du filtre, plus ou moins strictes (c est à dire que ces filtres n éliminent pas les memes caractères suivant les options choisies). 139

141 Rémy Malgouyres, Programmation Web En toute généralité, les options et les flags sont définis dans un tableau associatif (avec deux clés facultatives 'options' et/ou 'flags') de tableaux associatifs chaqu un de ces tableaux associatifs définissant les valeurs d une ou plusieurs options (pour le tableau $options['options']) ou d un ou plusieurs flags (pour le tableau $options['flags']). Partez pas! Je mets quelques exemples ci-dessous... Nous ne ferons pas ici une présentation exhaustive des utilisations des filtres ou des options. Pour celà voyez php.net. Nous donnons quelques exemples typiques Les filtres de Validation Les filtres de validation sont les valeurs possibles du deuxième paramètre filter de la fonction filter_var qui commencent par FILTER_VALIDATE_. Le but d un filtre de validation est de dire si une chaîne satisfait certaines condition ; si la forme de la chaîne est confrome à ce qu on attend d un certain type de données. La liste n est pas très longue. La plus grosse difficultés vient, comme d habitude, des conversions automatiques entre formats de nombre et booléens, qui produisent des résultats conteintuitifs qui peuvent conduire à des bugs a Le filtre FILTER_VALIDATE_BOOLEAN Ce filtre admet pas d option et admet FILTER_NULL_ON_FAILURE pour seul flag. Retourne TRUE pour 1, true, on et yes. RetourneFALSE sinon. Si le flag FILTER_NULL_ON_FAILURE est activé, FALSE n est retourné que pour les valeurs 0, false, off, no,, et NULL est retourné pour les valeurs non-booléennes. Ce filtre s applique à une chaine de caractères et ne donne pas le bon résultat sur une variable de type booléen (car les booléens FALSE ou TRUE ne sont pas des chaines de caractères représentant un booléen)! if (!is_bool($value)) { $value= filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE); } b Le filtre FILTER_VALIDATE_ Ce filtre valide une adresse e mail. N admet ni option, ni flag. Rien à signaler sur ce filtre c Le filtre FILTER_VALIDATE_FLOAT Ce filtre valide un nombre décimal. Le nombre flottant égal à zéro ($x = 0) est un nombre flottant valide, mais la fonction filter_var avec le filtre FILTER_VALIDATE_FLOAT, comme les données sont valides, va retourner la variable égale à 0, qui serait dans un test convertie en le booléen false). Le bon usage consiste à tester l identité de la donnée retournée par filter_var sans conversion, en utilisant les opérateurs === (vrai si deux variables ont des valeurs égales et on même type) ou!== (vrai si deux variables ont des valeurs différentes ou sont de types différents). 140

142 Chapitre 6 : Injection, Filtrage, Expressions Régulières exemples/filtrage/ex12_filtervarvalidatefloat.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>f i l t r e VALDATE_FLOAT</ t i t l e> 7 </head> 8 <body> 9 <h1>tests de <code>f i l t e r _ v a r</code><br/>avec f i l t r e <code> FILTER_VALIDATE_FLOAT</code></h1> 10 <?php 11 $x = 0 ; 12 i f ( f i l t e r _ v a r ( $x, FILTER_VALIDATE_FLOAT) ) { 13 echo $x e s t un f l o a t v a l i d e car. h t m l e n t i t i e s ( f i l t e r _ v a r ( $x, FILTER_VALIDATE_FLOAT), ENT_QUOTES, UTF 8 ) 14. vaut ; 15 var_dump( f i l t e r _ v a r ( $x, FILTER_VALIDATE_FLOAT) ) ; 16 echo <br/> ; 17 } e l s e { 18 echo $x n e s t pas un f l o a t v a l i d e car. h t m l e n t i t i e s ( f i l t e r _ v a r ( $x, FILTER_VALIDATE_FLOAT), ENT_QUOTES, UTF 8 ) 19. vaut ; 20 var_dump( f i l t e r _ v a r ( $x, FILTER_VALIDATE_FLOAT) ) ; 21 echo <br/> ; 22 } 23 i f ( f i l t e r _ v a r ( $x, FILTER_VALIDATE_FLOAT)!== f a l s e ) { 24 echo $x e s t bien sûr un f l o a t v a l i d e! <br/> ; 25 } e l s e { 26 echo $x n e s t pas un f l o a t v a l i d e <br/> ; 27 } 28?> 29 </body> 30 </html> if (filter_var($x, FILTER_VALIDATE_FLOAT)!== false) { echo "$x est un float valide"; } else { echo "$x n'est pas un float valide"; } d Le filtre FILTER_VALIDATE_INT Même remarque que pour les nombres réels à propos de l identité des variables à tester avec === ou!==, en raison du problème d un nombre égal à 0 (zéro) qui, converti en booléen, donnerait FALSE. Il y a des options permettant de tester un intervalle et des flags autorisant les écritures octales (style ) ou hexadécimales (style 0 x2c3f ) e Le filtre FILTER_VALIDATE_URL Ne fonctionne pas avec les URLs internationalisées (c est à dire avec des caractères non ASCII). Ces URLs doivent etre échappées auparavant. 141

143 Rémy Malgouyres, Programmation Web f Le filtre FILTER_VALIDATE_IP Valide une adresse IP? Admet des flags pour autoriser de manière sélective une adresse IPV4, IPV6, ou avec des plages d adresses réservées Les filtres de Nettoyage Les filtres de nettoyage permettent d appliquer un traitement à une chaîne pour la rendre conforme à la forme attendue des données. C est aussi une manière de sécuriser des données incorrectes sans renvoyer les données vers l utilisateur. Les filtres de nettoyage sont les valeurs possibles du deuxième paramètre de filter_var qui commencent par FILTER_SANITIZE, ce qui signifie en anglais rendre raisonnable, rendre hygiennique ou ramener à la raison. Le fait d appliquer un filtre de nettoyage améliore la sécurité mais, en général, cela ne permet pas de rendre coorectes des données incorrectes. Cela permet juste de rendre les données raisonnables. Par exemple, le filtre FILTER_SANITIZE_NUMBER_INT Supprime tous les caractères sauf les chiffres, et les signes plus et moins. Cela n empeche pas que si la donnée en entrée n est pas un nombre, le programme risque de ne pas fonctionner correctement. Le filtre FILTER_SANITIZE_STRING permet de supprimer ou d encoder diiférents jeux de caractères spéciaux (suivant la valeur du flag) Le filtre personnalisé FILTER_CALLBACK Ce filtre est un exemple dans lequel on va fournir à filter_var une fonction callback personnalisée, que l on codera soi-même, et qui sera appelée automatiquement filter_var pour valider ou nettoyer une chaîne. Voici un exemple de validation par expression régulière (voir plus loin dans ce chapitre). exemples/filtrage/ex13_filtervarcallback.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>post un Nom</ t i t l e> 7 </head> 8 <body> 9 <h1>tests de <code>f i l t e r _ v a r</code><br/>avec f i l t r e <code>filter_callback</ code></h1> 10 <?php 11 f u n c t i o n numerotelephone ( $ t e l ) { 12 i f ( preg_match ( /^(((\+33 ) 0 ) {1}[0 9]{1}([ ]{0,1}[0 9]{2}) {4}) $ /, $ t e l ) ) { 13 return $ t e l ; 14 } e l s e { 15 return f a l s e ; 16 } 17 } $telephone = ; 20 i f ( f i l t e r _ v a r ( $telephone, FILTER_CALLBACK, 21 array ( options => numerotelephone ) )!==f a l s e ) { 142

144 Chapitre 6 : Injection, Filtrage, Expressions Régulières 22 echo numéro de téléphone v a l i d e.<br/> ; 23 } e l s e { 24 echo numéro de téléphone i n v a l i d e.<br/> ; 25 } 26?> 27 </body> 28 </html> 6.4 Expressions régulières Les expressions régulières sont un moyen de vérifier d une manière très générale qu une chaîne de caractère a une certaine forme. L extension PRCE en PHP permet, via des fonctions comme preg_match, de vérifier qu une chaîne est conforme à une expression régulière. Un bon tutorial sur la syntaxe et l utilisation des expressions régulières en PHP se trouve à l adresse suivante : Exemples. Par exemple, pour valider un nom ou un prénom entre 1 et 50 caractères alphabétiques français avec des espaces ou traits d unions, on peut utiliser quelque-chose du genre : /^(([a-za-zàâéèêôùûçàâéèôùûçäöëüäöëü](\- ( )*)){1,50})$/ Notez que pour que le filtrage puisse servir à éviter les injections, il ne faut pas omettre le au début et le $ à la fin de l expression pour que l expression régulière représente l ensemble de l input utilisateur et non pas simplement une sous-chaîne. Le filtrage d une chaine de caractères accentués (au moins en français) peut se faire un plus sytématiquement après échappement par : '/^([a-za-z]'.' (\&[a-za-z]grave\;) (\&[a-za-z]acute\;) (\&[a-za-z]circ\;) (\&[a-za-z]uml\;)'.' (\&[a-za-z]cedil\;) (\&[a-za-z][a-za-z]lig\;) (\&szlig\;) (\&[a-za-z]tilde\;)'.' (\-) ( ) (\&\#039\;) (\&quot\;) (\.)))+$/' Le filtrage avec preg_match se fait alors par un code du genre : 143

145 Rémy Malgouyres, Programmation Web exemples/filtrage/ex14_regexaccents.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>v a l i d a t i o n de chaîne accentuée</ t i t l e> 7 </head> 8 <body> 9 <h1>v a l i d a t i o n de chaîne accentuée échappée<br/> ( au moins en f r a n ç a i s )</h1> 10 <?php 11 $chaine = h t m l e n t i t i e s ( àà àèèà ÈéÉed atjjê ÊËä æ œ \., ENT_QUOTES) ; 12 echo Chaîne. h t m l e n t i t i e s ( $chaine, ENT_QUOTES) ; 13 i f ( preg_match ( / ^ ( [ a za Z ] 14. ( \ & [ a za Z ] grave \ ; ) ( \ & [ a za Z ] acute \ ; ) ( \ & [ a za Z ] c i r c \ ; ) ( \ & [ a za Z ] uml \ ; ) // c a r a c t è r e s accentués 15. ( \ & [ a za Z ] c e d i l \ ; ) ( \ & [ a za Z ] [ a za Z ] l i g \ ; ) (\& s z l i g \ ; ) ( \ & [ a za Z ] t i l d e \ ; ) // c a r a c t è r e s accentués 16. ( \ ) ( ) (\&\#039\ ;) (\& quot \ ; ) ( \. ) )+$ /, // Espaces, t r a i t d union, s i m p l e s et doubles quotes 17 $chaine ) ) { 18 echo <strong>v a l i d e</strong> ; 19 } e l s e { 20 echo <strong>i n v a l i d e</strong> ; 21 } 22?> 23 </body> 24 </html> Pour un numéro de téléphone français sous la forme de 10 chiffres commençant par 0 et par groupes de deux séparés par des espaces : /^(0{1}[0-9]{1}( [0-9]{2}){4})$/ En option, avec un +33 devant pour les appels internationaux : /^(((\+33 ) 0){1}[0-9]{1}( [0-9]{2}){4})$/ En option, avec un +33 devant pour les appels internationaux et les espaces entre chiffres optionnels : /^(((\+33 ) 0){1}[0-9]{1}([ ]{0,1}[0-9]{2}){4})$/ En option, avec la possibilité de ne pas laisser d espaces ou de mettre des tires ou des points entre les groupes de chiffres (exemples : ) : /^(((\+33( \- \.)) 0){1}[0-9]{1}(( \- \.)[0-9]{2}){4})$/ 144

146 Chapitre 7 Formulaires PHP/HTML, filtrage, exceptions Dans ce chapitre, nous proposons une conception de classes métiers et classes d utilitaires pour générer des vues HTML. La gestion des données saisies par l utilisateur nous conduit, au vu du chapitre 6, à gérer plus rigoureusement le filtrage. Nous distinguons deux types de filtrage des données : 1. Le filtrage pour la sécurité, qui sera géré par des fonctions de validation ou de nettoyage systématique (comme filter_var) ou dans le cas de la couche de persistance basée sur PDO, par la préparation systématique des requêtes. 2. Le filtrage pour la cohérence des données, qui nécessite généralement un connaissance de la sémantique des objets métiers et de leurs attributs, est se fonde le plus souvent sur des tests d expressions régulières. Dans notre implémentation, ce filtrage sera réalisé dans les setters des classes de représentation des données métier. 7.1 La Classe Adresse Nous reprenons à peu près la classe adresse de la partie Nous ajoutons : 1. Un filtrage pour la cohérence des données un peu plus réaliste au niveau des setters ; 2. Une méthode statique permettant d avoir une adresse par défaut (exemple : les champs vides pour initialiser un formulaire en utilisant la classe AdresseFormView ci-dessous). exemples/forms2/ex01_classeadresse.php 1 <?php 2 require_once ( dirname ( FILE ). / ExpressionsRegexUtils. php ) ; 3 require_once ( dirname ( FILE ). / A d r e s s e P r o p e r t i e s T r a i t. php ) ; 4 5 //////////////////////////////////////////////////////////// 6 // Classe Adresse : 7 8 /** La c l a s s e a d r e s s e c o n t i e n t l a d r e s s e d une personne 10 ( qui peut ê t r e un c l i e n t, un employé, un f o u r n i s s e u r, e t c... ) 145

147 Rémy Malgouyres, Programmation Web 11 */ 12 class Adresse { 13 p r i v a t e $id ; 14 /** Numéro dans l a rue, ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 15 p r i v a t e $numerorue ; 16 /** Nom de l a rue, ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 17 p r i v a t e $rue ; 18 /** Complément ( l i e u dit, e t c. ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 19 p r i v a t e $complementadresse ; 20 /** code p o s t a l */ 21 p r i v a t e $codepostal ; 22 /** nom de l a v i l l e. ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 23 p r i v a t e $ v i l l e ; 24 /** nom du pays. ne d o i t pas ê t r e n u l l mais peut ê t r e vide */ 25 p r i v a t e $pays ; // I n c l u s i o n du t r a i t A d r e s s e P r o p e r t i e s d é f i n i s s a n t l e s a c c e s s e u r s et s e t t e r s 28 use A d r e s s e P r o p e r t i e s ; 29 : Accesseur : permet d o b t e n i r l e numéro dans l a rue. */ /** 32 Génère 10 c h i f f r e s hexa a l é a t o i r e s ( s o i t 5 o c t e t s ) : 33 */ 34 p r i v a t e s t a t i c f u n c t i o n generaterandomid ( ) 35 { 36 // Génération de 5 o c t e t s ( pseudo ) a l é a t o i r e s codés en hexa 37 $cryptostrong = f a l s e ; // Variable pour passage par r é f é r e n c e 38 $ o c t e t s = openssl_random_pseudo_bytes ( 5, $cryptostrong ) ; 39 return bin2hex ( $ o c t e t s ) ; 40 } /** Constructeur : i n i t i a l i s e l e s a t t r i b u t s à p a r t i r des paramètres. 44 Les paramètres correspondent aux v a l e u r s à mettre dans l e s a t t r i b u t s. 45 Tout o b j e t d o i t ê t r e i n i t i a l i s é avec l e c o n s t r u c t e u r ( appel à new ). 46 Des e x c e p t i o n s sont r e j e t é e s en cas de paramètre i n v a l i d e. 47 */ 48 p u b l i c f u n c t i o n construct ( $id, $numerorue, $rue, $complementadresse, $codepostal, $ v i l l e, $pays ) { 49 $ t h i s > setnumerorue ( $numerorue ) ; 50 $ t h i s > setrue ( $rue ) ; 51 $ t h i s > setcomplementadresse ( $complementadresse ) ; 52 $ t h i s > setcodepostal ( $codepostal ) ; 53 $ t h i s > s e t V i l l e ( $ v i l l e ) ; 54 $ t h i s > setpays ( $pays ) ; 55 } /** 58 c o n s t r u i t une Adresse par défaut 59 * Remarque : on ne peut pas s u r c h a r g e r l e s c o n s t r u c t e u r s en PHP */ 61 p u b l i c s t a t i c f u n c t i o n g etdefaultadresse ( ) { 62 // On a p p e l l e l e c o n s t r u c t e u r avec des arguments convenables 63 // en terme d e x p r e s s i o n s r é g u l i è r e s 64 $ a d r e s s e = new Adresse ( 33, 2, Rue,, 12345, V i l l e, Pays ) ; 65 $adresse >id = s e l f : :generaterandomid ( ) ; 146

148 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 66 $adresse >numerorue = ; 67 $adresse >rue = ; 68 $adresse >complementadresse = ; 69 $adresse >codepostal = ; 70 $adresse >v i l l e = ; 71 $adresse >pays = France ; 72 return $ a d r e s s e ; 73 } 74 } 75?> 7.2 Filtrage des attributs Nous proposons tout d abord des méthodes génériques de test d expressions régulières pour la langue française, avec ou sans chiffres. Ces expressions régulières doivent être testées après échappement par htmlentities, ce qui permet une approche générique du traitement des accents (exemple : é, des apostrophes, guillemets (simple ou doubles quotes), etc. qui peuvent apparaître en français. exemples/forms2/ex02_expressionsregexutils.php 1 <?php 2 ///////////////////////////////////////////////////////////////// 3 // Expressions r é g u l i è r e s u t i l e s. 4 class ExpressionsRegexUtils { 5 6 /** 7 : e x p r e s s i o n r é g u l i è r e pour l a langue Française avec a c c e n t s 8 La chaîne d o i t ê t r e échappée par h t m l e n t i t i e s 9 */ 10 p r i v a t e s t a t i c f u n c t i o n getregexfrlang ( ) { 11 return / ^ ( [ a za Z ] 12. ( \ & [ a za Z ] grave \ ; ) ( \ & [ a za Z ] acute \ ; ) ( \ & [ a za Z ] c i r c \ ; ) ( \ & [ a za Z ] uml \ ; ) 13. ( \ & [ a za Z ] c e d i l \ ; ) ( \ & [ a za Z ] [ a za Z ] l i g \ ; ) (\& s z l i g \ ; ) ( \ & [ a za Z ] t i l d e \ ; ) 14. ( \ ) ( ) (\&amp\ ;\#39\ ;) (\&\#039\ ;) (\&amp\ ;\#34\ ;) (\&\#034\ ;) (\& quot \ ; ) ( \. ) ) *$ / ; 15 } /** 18 : e x p r e s s i o n r é g u l i è r e pour l a langue Française avec a c c e n t s et c h i f f r e s 19 La chaîne d o i t ê t r e échappée par h t m l e n t i t i e s 20 */ 21 p r i v a t e s t a t i c f u n c t i o n getregexfrlangwithnumbers ( ) { 22 return / ^ ( [ a za Z0 9] 23. ( \ & [ a za Z ] grave \ ; ) ( \ & [ a za Z ] acute \ ; ) ( \ & [ a za Z ] c i r c \ ; ) ( \ & [ a za Z ] uml \ ; ) 24. ( \ & [ a za Z ] c e d i l \ ; ) ( \ & [ a za Z ] [ a za Z ] l i g \ ; ) (\& s z l i g \ ; ) ( \ & [ a za Z ] t i l d e \ ; ) 25. ( \ ) ( ) (\&amp\ ;\#39\ ;) (\&\#039\ ;) (\&amp\ ;\#34\ ;) (\&\#034\ ;) (\& quot \ ; ) ( \. ) ) *$ / ; 26 } 147

149 Rémy Malgouyres, Programmation Web /** 29 : Test e x p r e s s i o n r é g u l i è r e pour l a langue Française avec a c c e n t s 30 * avec c o n d i t i o n s de longueur ( par exemple pour un champ o b l i g a t o i r e ) 31 */ 32 p u b l i c s t a t i c f u n c t i o n isvalidregexfrlang ( $chaine, $minlenth, $maxlenth ) { 33 return ( i s s e t ( $chaine ) && 34 s t r l e n ( $chaine ) >= $minlenth && s t r l e n ( $chaine ) <= $maxlenth 35 && preg_match ( s e l f : :getregexfrlang ( ), $chaine ) ) ; 36 } /** 39 : Test e x p r e s s i o n r é g u l i è r e pour l a langue Française avec a c c e n t s et c h i f f r e s 40 * avec c o n d i t i o n s de longueur ( par exemple pour un champ o b l i g a t o i r e ) 41 */ 42 p u b l i c s t a t i c f u n c t i o n isvalidregexfrlangwithnumbers ( $chaine, $minlenth, $maxlenth ) { 43 return ( i s s e t ( $chaine ) && 44 s t r l e n ( $chaine ) >= $minlenth && s t r l e n ( $chaine ) <= $maxlenth 45 && preg_match ( s e l f : :getregexfrlangwithnumbers ( ), $chaine ) ) ; 46 } /** 49 : Test e x p r e s s i o n r é g u l i è r e passée en paramètre 50 * avec c o n d i t i o n s de longueur ( par exemple pour un champ o b l i g a t o i r e ) 51 */ 52 p u b l i c s t a t i c f u n c t i o n i s V a l i d S t r i n g ( $chaine, $regexp, $minlenth, $maxlenth ) { 53 return ( i s s e t ( $chaine ) && 54 s t r l e n ( $chaine ) >= $minlenth && s t r l e n ( $chaine ) <= $maxlenth 55 && preg_match ( $regexp, $chaine ) ) ; 56 } 57 } 58?> Dans notre implémentation, nous réalisons les tests de cohérence des données par expressions régulières au niveau des setters des classes métier. Nous réalisons au préalable, dans le setter, un échappement par htmlentities, de manière à pouvoir gérer les apostrophes ou guillemets, qui seraient sinon rejetées lors du filtrage destiné à éviter les injections SQL (par exemple dans les requêtes préparées PDO). Cet échappement par htmlentities nous permet aussi d utiliser les expressions régulières génériques ci-dessus. exemples/forms2/ex03_classeadressepropertiestrait.php 1 <?php 2 /** La c l a s s e a d r e s s e c o n t i e n t l a d r e s s e d une personne 4 ( qui peut ê t r e un c l i e n t, un employé, un f o u r n i s s e u r, e t c... ) 5 */ 6 t r a i t A d r e s s e P r o p e r t i e s { 7 Accesseur : permet d o b t e n i r l id de l a d r e s s e. */ 8 p u b l i c f u n c t i o n getid ( ) { 9 return $ t h i s >id ; 10 } Accesseur : permet d o b t e n i r l e numéro dans l a rue. */ 148

150 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 13 p u b l i c f u n c t i o n getnumerorue ( ) { 14 return html_entity_decode ( $ t h i s >numerorue, ENT_QUOTES, UTF 8 ) ; 15 } Accesseur : permet d o b t e n i r l e nom l a rue. */ 18 p u b l i c f u n c t i o n getrue ( ) { 19 return html_entity_decode ( $ t h i s >rue, ENT_QUOTES, UTF 8 ) ; 20 } Accesseur : permet d o b t e n i r l e nom l e complément d a d r e s s e. */ 23 p u b l i c f u n c t i o n getcomplementadresse ( ) { 24 return html_entity_decode ( $ t h i s >complementadresse, ENT_QUOTES, UTF 8 ) ; 25 } Accesseur : permet d o b t e n i r l e nom l e code p o s t a l. */ 28 p u b l i c f u n c t i o n getcodepostal ( ) { 29 return html_entity_decode ( $ t h i s >codepostal, ENT_QUOTES, UTF 8 ) ; 30 } Accesseur : permet d o b t e n i r l e nom l a v i l l e. */ 33 p u b l i c f u n c t i o n g e t V i l l e ( ) { 34 return html_entity_decode ( $ t h i s >v i l l e, ENT_QUOTES, UTF 8 ) ; 35 } Accesseur : permet d o b t e n i r l e pays. */ 39 p u b l i c f u n c t i o n getpays ( ) { 40 return html_entity_decode ( $ t h i s >pays, ENT_QUOTES, UTF 8 ) ; 41 } /** 44 s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a rue. 45 $id l i d e n t i f i a n t de l a d r e s s e (10 c h i f f r e s hexa ). 46 */ 47 p u b l i c f u n c t i o n s e t I d ( $id ) { 48 i f (! i s s e t ( $id )! preg_match ( /^[0 9a f ]{10} $/, $id ) ) { 49 throw new Exception ( Erreur, i d e n t i f i a n t i n c o r r e c t ) ; 50 } 51 $ t h i s >id = $id ; 52 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a rue. $NumeroRue l e numéro à u t i l i s e r. peut ê t r e n u l l. 56 */ 57 p u b l i c f u n c t i o n setnumerorue ( $numerorue ) { 58 $escaped = h t m l e n t i t i e s ( $numerorue, ENT_QUOTES, UTF 8 ) ; 59 i f (! ExpressionsRegexUtils : :isvalidregexfrlangwithnumbers ( $escaped, 0, 50) ) { 60 throw new Exception ( Erreur, l e numéro de l a rue d o i t comporter 61. au plus 50 c a r a c t è r e s 62. ( alphabétiques, c h i f f r e s ou ponctuation ) ) ; 63 } 64 $ t h i s >numerorue = empty ( $escaped )? : $escaped ; 65 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e numéro dans l a rue. $Rue l e nom de l a rue ou de l a p l a c e à u t i l i s e r. peut ê t r e n u l l. 149

151 Rémy Malgouyres, Programmation Web 69 */ 70 p u b l i c f u n c t i o n setrue ( $rue ) { 71 $escaped = h t m l e n t i t i e s ( $rue, ENT_QUOTES, UTF 8 ) ; 72 i f (! ExpressionsRegexUtils : :isvalidregexfrlangwithnumbers ( $escaped, 1, 150) ) { 73 throw new Exception ( Erreur, l e nom de l a rue, o b l i g a t o i r e 74. d o i t comporter au plus 150 c a r a c t è r e s 75. ( alphabétiques, c h i f f r e s ou ponctuation ) ) ; 76 } 77 $ t h i s >rue = empty ( $escaped )? : $escaped ; 78 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e complément d a d r e s s e. $complementadresse l e complément d a d r e s s e à u t i l i s e r. peut ê t r e n u l l. 82 */ 83 p u b l i c f u n c t i o n setcomplementadresse ( $complementadresse ) { 84 $escaped = h t m l e n t i t i e s ( $complementadresse, ENT_QUOTES, UTF 8 ) ; 85 i f (! ExpressionsRegexUtils : :isvalidregexfrlangwithnumbers ( $escaped, 0, 150) ) { 86 throw new Exception ( Erreur, l e Complément d a d r e s s e \. $complementadresse 87. \ d o i t comporter au plus 150 c a r a c t è r e s 88. ( alphabétiques, c h i f f r e s ou ponctuation ) ) ; 89 } 90 $ t h i s >complementadresse = empty ( $escaped )? : $escaped ; 91 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e code p o s t a l. $CodePostal l e numéro à u t i l i s e r. peut ê t r e n u l l 95 */ 96 p u b l i c f u n c t i o n setcodepostal ( $codepostal ) { 97 $escaped = h t m l e n t i t i e s ( $codepostal, ENT_QUOTES, UTF 8 ) ; 98 i f (! ExpressionsRegexUtils : :isvalidregexfrlangwithnumbers ( $escaped, 1, 20) ) { 99 throw new Exception ( Erreur, l e code p o s t a l n e s t pas v a l i d e 100. ( code p o s t a l f r a n c e m é t r o p o l i t a i n e sans cedex ni B.P. ) ) ; 101 } 102 $ t h i s >codepostal = empty ( $escaped )? : $escaped ; 103 } s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom de l a v i l l e. $ V i l l e l e nom de l a v i l l e à u t i l i s e r. peut ê t r e n u l l 107 */ 108 p u b l i c f u n c t i o n s e t V i l l e ( $ v i l l e ) { 109 $escaped = h t m l e n t i t i e s ( $ v i l l e, ENT_QUOTES, UTF 8 ) ; 110 i f (! ExpressionsRegexUtils : :isvalidregexfrlang ( $escaped, 1, 150) ) { 111 throw new Exception ( Erreur, l e nom de l a v i l l e \. $ v i l l e. \, 112. o b l i g a t o i r e d o i t comporter au plus 150 c a r a c t è r e s 113. ( a l p h a b é t i q u e s ou ponctuation ) ) ; 114 } 115 $ t h i s >v i l l e = empty ( $escaped )? : $escaped ; 116 }

152 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 118 s e t t e r : permet d i n i t i a l i s e r ou de m o d i f i e r l e nom du Pays $pays l e nom du Pays à u t i l i s e r. peut ê t r e n u l l 120 */ 121 p u b l i c f u n c t i o n setpays ( $pays ) { 122 $escaped = h t m l e n t i t i e s ( $pays, ENT_QUOTES, UTF 8 ) ; 123 i f (! ExpressionsRegexUtils : :isvalidregexfrlang ( $escaped, 1, 100) ) { 124 throw new Exception ( Erreur, l e nom du Pays, o b l i g a t o i r e d o i t 125. comporter au plus 100 c a r a c t è r e s 126. ( a l p h a b é t i q u e s ou ponctuation ) ) ; 127 } 128 $ t h i s >pays = empty ( $escaped )? : $escaped ; 129 } 130 } 131?> 7.3 Fabrique d Adresse Nous présentons aussi une fabrique d adresses qui construit des instances à partir de données issues d un formulaire, tout en construisant un tableau d erreurs en cas d exception générée au niveau des setters. Le tableau d erreurs $dataerrors, passé par références, contiendra des couples clé/valeur, dont la clé sera le nom de l attribut de la classe Adresse et la valeur sera le messages de l exception générée dans le setter de cet attribut. Si aucune exception n est générée dans les setter, le tableau d erreurs est vide. exemples/forms2/ex06_classeadressefabrique.php 1 <?php 2 require_once ( dirname ( FILE ). / Adresse. php ) ; 3 4 /** La c l a s s e AdresseFabrique implémente l a c o n s t r u c t i o n d un o b j e t Adresse 6 * à p a r t i r des données s a i s i e s dans un f o r m u l a i r e 7 * Les e r r e u r s g é n é r é e s dans l e s s e t t e r s ( r e ç u e s via des e x c e p t i o n s ) sont accumulées 8 * dans un tableau a s s o c i a t i f d e r r e u r s, pour g é n é r e r l e cas échéant une vue d e r r e u r. 9 **/ 10 class AdresseFabrique { /** Obtension d un o b j e t de c l a s s e Adresse à p a r t i r des 14 données s a i s i e s dans un f o r m u l a i r e. 15 Cette méthode prend l e s mêmes paramètres que l e c o n s t r u c t e u r 16 plus un paramètre passé par r é f é r e n c e qui r e t o u r n e l e s messages d e x c e p t i o n. 17 I n i t i a l i s e l e s a t t r i b u t s à p a r t i r des paramètre. 18 Pour chaque a t t r i b u t e de l a c l a s s e, s i une e x c e p t i o n e s t générée 19 au niveau du s e t t e r, l e message d e x c e p t i o n e s t a j o u t é dans un tableau a s s o c i a t i f d e r r e u r s. 20 * Ces messages d e x c e p t i o n sont 21 a i n s i renvoyés au c o n t r ô l e u r. 22 */ 23 p u b l i c s t a t i c f u n c t i o n getadresse (&$dataerrors, $id, $numerorue, $rue, 24 $complementadresse, $codepostal, $ v i l l e, $pays ) { 25 $adr = Adresse : :g etdefaultadresse ( ) ; 151

153 Rémy Malgouyres, Programmation Web 26 $dataerrors = array ( ) ; try { 29 $adr > s e t I d ( $id ) ; 30 } catch ( Exception $e ) { 31 $dataerrors [ id ] = $e >getmessage ( ). <br/>\n ; 32 } 33 try { 34 $adr > setnumerorue ( $numerorue ) ; 35 } catch ( Exception $e ) { 36 $dataerrors [ numerorue ] = $e >getmessage ( ). <br/>\n ; 37 } 38 try { 39 $adr > setrue ( $rue ) ; 40 } catch ( Exception $e ) { 41 $dataerrors [ rue ] = $e >getmessage ( ). <br/>\n ; 42 } 43 try { 44 $adr > setcomplementadresse ( $complementadresse ) ; 45 } catch ( Exception $e ) { 46 $dataerrors [ complementadresse ] = $e >getmessage ( ). <br/>\n ; 47 } 48 try { 49 $adr > setcodepostal ( $codepostal ) ; 50 } catch ( Exception $e ) { 51 $dataerrors [ codepostal ] = $e >getmessage ( ). <br/>\n ; 52 } 53 try { 54 $adr > s e t V i l l e ( $ v i l l e ) ; 55 } catch ( Exception $e ) { 56 $dataerrors [ v i l l e ] = $e >getmessage ( ). <br/>\n ; 57 } 58 try { 59 $adr > setpays ( $pays ) ; 60 } catch ( Exception $e ) { 61 $dataerrors [ pays ] = $e >getmessage ( ). <br/>\n ; 62 } 63 return $adr ; 64 } 65 } 66?> 7.4 Génération de formulaires et classe AdresseFormView Nous définissons ensuite la classe AdresseFormView qui présente (essentiellement) deux méthodes pour générer des formulaires, avec ou sans gestion d erreur dans des vues. Un méthode permet aussi de générer un formulaire avec tous les champs cachés pour transmettre tous les champs d une adresse par la méthode post de manière transparente pour l utilisateur. Pour générer des formulaires, on utilise une classe template de génération de formulaires dont le code est donné ci-dessous. Dans la méthode permettant de générer le formulaire avec un éventuel message d erreur pour chaque attribut, on utilise le format du tableau d erreurs construit par la fabrique d adresse (partie 7.3). 152

154 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions exemples/forms2/ex04_classeadresseformview.php 1 <?php 2 require_once ( dirname ( FILE ). / Adresse. php ) ; 3 require_once ( dirname ( FILE ). / FormManager. php ) ; 4 5 /** La c l a s s e AdresseFormView implémente l a g é n é r a t i o n d un f o r m u l a i r e HTML pour s a i s i r 7 * une a d r e s s e dans une vue dans un navigareur. 8 * Implémente a u s s i des u t i l i s t a i r e s de c o n v e r s i o n à p a r t i r d une Adresse 9 * pour o b t e n i r f a c i l e m e n t l e code HTML pour a f f i c h e r une Adresse. 10 */ 11 class AdresseFormView { /** 14 Méthode de g é n é r a t i o n d HTML. Permet d a f f i c h e r une a d r e s s e en HTML. 15 * La méthode retourne l e code HTML avec des r e t o u r à l a l i g n e pour un a f f i c h a g e c o n v i v i a l. 16 */ 17 p u b l i c s t a t i c f u n c t i o n getdefaultformhtml ( $ a c t i o n ) { 18 return s e l f : :getformhtml ( $action, Adresse : :g e t D e f a u l t A d r e s s e ( ) ) ; 19 } /** 22 Méthode de g é n é r a t i o n d HTML. Permet d a f f i c h e r une a d r e s s e en HTML. 23 * La méthode retourne l e code HTML avec des r e t o u r à l a l i g n e pour un a f f i c h a g e c o n v i v i a l. 24 */ 25 p u b l i c s t a t i c f u n c t i o n getformhtml ( $action, $ a d r e s s e ) { 26 $htmlcode = FormManager : :beginform ( post, $ a c t i o n ) ; 27 $htmlcode.= FormManager : :addhiddeninput ( id, id, $adresse >g e t I d ( ) ) ; 28 $htmlcode.= FormManager : :addtextinput ( Numéro, numerorue, numerorue, 4, 29 $adresse >getnumerorue ( ) ). <br/> ; 30 $htmlcode.= FormManager : :addtextinput ( Rue/ p l a c e, rue, rue, 30, 31 $adresse >getrue ( ) ). <br/> ; 32 $htmlcode.= FormManager : :addtextinput ( Complément d a d r e s s e, 33 complementadresse, complementadresse, 34 30, $adresse >getcomplementadresse ( ) ). <br/> ; 35 $htmlcode.= FormManager : :addtextinput ( Code p o s t a l, codepostal, codepostal, 10, $adresse > getcodepostal ( ) ). <br/> ; 36 $htmlcode.= FormManager : :addtextinput ( V i l l e, v i l l e, v i l l e, 20, 37 $adresse >g e t V i l l e ( ), ENT_QUOTES, UTF 8 ). <br /> ; 38 $htmlcode.= FormManager : :addtextinput ( Pays, pays, pays, 15, 39 $adresse >getpays ( ) ). <br/> ; 40 $htmlcode.= FormManager : :addsubmitbutton ( Envoyer, c l a s s =\ sanslabel \ ). <br/> ; 41 $htmlcode.= FormManager : :endform ( ) ; return $htmlcode ; 44 }

155 Rémy Malgouyres, Programmation Web p r i v a t e s t a t i c f u n c t i o n adderrormsg ( $dataerrors, $fieldname ) { 48 i f (! empty ( $dataerrors [ $fieldname ] ) ) { 49 $htmlcode.= <span c l a s s =\ errormsg \ >. $dataerrors [ $fieldname ]. </span ><br/> ; 50 } 51 return $htmlcode ; 52 } /** 55 Méthode de g é n é r a t i o n d HTML. Permet d a f f i c h e r une a d r e s s e en HTML 56 * en a f f i c h a n t l e s e r r e u r s précédement d é t e c t é e sur l e s d i f f é r e n t s a t t r i b u t s. 57 * La méthode retourne l e code HTML avec des r e t o u r à l a l i g n e pour un a f f i c h a g e c o n v i v i a l. 58 */ 59 p u b l i c s t a t i c f u n c t i o n getformerrorshtml ( $action, $adresse, $dataerrors ) { 60 $htmlcode = FormManager : :beginform ( post, $ a c t i o n ) ; 61 $htmlcode.= FormManager : :addhiddeninput ( id, id, $adresse >g e t I d ( ) ) ; 62 $htmlcode.= s e l f : :adderrormsg ( $dataerrors, numerorue ) ; 63 $htmlcode.= FormManager : :addtextinput ( Numéro, numerorue, numerorue, 4, 64 $adresse >getnumerorue ( ) ). <br/> ; 65 $htmlcode.= s e l f : :adderrormsg ( $dataerrors, rue ) ; 66 $htmlcode.= FormManager : :addtextinput ( Rue/ p l a c e, rue, rue, 30, 67 $adresse >getrue ( ) ). <br/> ; 68 $htmlcode.= s e l f : :adderrormsg ( $dataerrors, complementadresse ) ; 69 $htmlcode.= FormManager : :addtextinput ( Complément d a d r e s s e, 70 complementadresse, complementadresse, 71 30, $adresse >getcomplementadresse ( ) ). <br/> ; 72 $htmlcode.= s e l f : :adderrormsg ( $dataerrors, codepostal ) ; 73 $htmlcode.= FormManager : :addtextinput ( Code p o s t a l, codepostal, codepostal, 10, $adresse > getcodepostal ( ) ). <br/> ; 74 $htmlcode.= s e l f : :adderrormsg ( $dataerrors, v i l l e ) ; 75 $htmlcode.= FormManager : :addtextinput ( V i l l e, v i l l e, v i l l e, 20, 76 $adresse >g e t V i l l e ( ), ENT_QUOTES, UTF 8 ). <br /> ; 77 $htmlcode.= s e l f : :adderrormsg ( $dataerrors, pays ) ; 78 $htmlcode.= FormManager : :addtextinput ( Pays, pays, pays, 15, 79 $adresse >getpays ( ) ). <br/> ; 80 $htmlcode.= FormManager : :addsubmitbutton ( Envoyer, c l a s s =\ sanslabel \ ). <br/> ; 81 $htmlcode.= FormManager : :endform ( ) ; return $htmlcode ; 84 } /** 87 Méthode de g é n é r a t i o n d HTML. Permet d a f f i c h e r une a d r e s s e en HTML. 88 * La méthode retourne l e code HTML avec des r e t o u r à l a l i g n e pour un a f f i c h a g e c o n v i v i a l. 89 */ 90 p u b l i c s t a t i c f u n c t i o n gethiddenformhtml ( $action, $adresse, $buttontext ) { 91 $htmlcode = FormManager : :beginform ( post, $ a c t i o n ) ; 154

156 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 92 $htmlcode.= FormManager : :addhiddeninput ( id, id, $adresse >g e t I d ( ) ) ; 93 $htmlcode.= FormManager : :addhiddeninput ( numerorue, numerorue, 94 $adresse >getnumerorue ( ) ) ; 95 $htmlcode.= FormManager : :addhiddeninput ( rue, rue, $adresse >getrue ( ) ) ; 96 $htmlcode.= FormManager : :addhiddeninput ( complementadresse, complementadresse, 97 $adresse >getcomplementadresse ( ) ) ; 98 $htmlcode.= FormManager : :addhiddeninput ( codepostal, codepostal, 99 $adresse >getcodepostal ( ) ) ; 100 $htmlcode.= FormManager : :addhiddeninput ( v i l l e, v i l l e, $adresse > g e t V i l l e ( ) ) ; 101 $htmlcode.= FormManager : :addhiddeninput ( pays, pays, $adresse >getpays ( ) ) ; 102 $htmlcode.= FormManager : :addsubmitbutton ( $buttontext, c l a s s =\ sanslabel \ ) ; 103 $htmlcode.= FormManager : :endform ( ) ; return $htmlcode ; 106 } } 109?> La classe template de génération de formulaires utilisée ci-dessous est la suivante : exemples/forms2/ex05_classeformmanager.php 1 <?php 2 /** Cette c l a s s e s e r t à f a c i l i t é l a g é n é r a t i o n de f o r m u l a i r e s HTML en PHP. 4 * E l l e f o u r n i t de méthodes pour g é n é r e r l e début, l a f i n du f o r m u l a i r e, 5 * a i n s i que l e s inputs avec l e s o p t i o n s de base. 6 * Les o p t i o n s complémentaires des i nputs peuvent ê t r e s é l e c t i o n n é e s 7 * via une v a r i a b l e $extraoptions des méthodes ( mais c e s t un peu plus complexe ). 8 **/ 9 class FormManager { 10 /** génère l a b a l i s e form avec sa méthode ( Post ou Get ) et sont action ( u r l ) 12 */ 13 p u b l i c s t a t i c f u n c t i o n beginform ( $method, $action, $ c s s _ c l a s s=, $extraoptions= ) { 14 i f (! empty ( $ c s s _ c l a s s ) ) 15 $css_class_option = c l a s s =\. $ c s s _ c l a s s. \ ; 16 return <form method=\. $method. \ a c t i o n=\. $ a c t i o n. \. $css_class_option. $extraoptions. >\n ; 17 } /** ferme l e f o r m u l a i r e 21 */ 22 p u b l i c s t a t i c f u n c t i o n endform ( ) { 23 return </form> ; 24 }

157 Rémy Malgouyres, Programmation Web 26 /** 27 méthode g énérique de g é n é r a t i o n d un input $labeltext t e x t e du label correspondant à l input $type type d input : t e x t e textarea, chackbox, radio, submit... $id ID de l input pour l a correspondance label /input $value v a l e u r i n i t i a l e du champs de l input $extraoptions chaine de c a r a c t è r e s contenant l e s o p t i o n s supplémentaires 33 de l input suivant l a syntaxe HTML. 34 */ 35 p u b l i c s t a t i c f u n c t i o n addinput ( $labeltext, $type, $name, $id, $value=null, $extraoptions=, $nobr=f a l s e ) { 36 $valueoption = ( $value == n u l l )? : value=\. $value. \ ; 37 i f ( $extraoptions == n u l l ) { 38 $extraoptions= ; 39 } i f ( $labeltext!= n u l l && $labeltext!= ) { 42 $returntext.= <l a b e l f o r=\. $id. \ >. $labeltext. </l a b e l >\n ; 43 } 44 $returntext.= <input type=\. $type. \ name=\. $name. \ id=\. $id. \. $valueoption.. $extraoptions. />\n ; i f (! $nobr) { 47 $returntext.= <br/>\n ; 48 } 49 return $returntext ; 50 } /** méthode s i m p l i f i é e pour g é n é r e r un input de type text 54 */ 55 p u b l i c s t a t i c f u n c t i o n addtextinput ( $labeltext, $name, $id, $ s i z e, $value=null, $extraoptions= ) { 56 return s e l f : :addinput ( $labeltext, t e x t, $name, $id, $value, s i z e =\. $ s i z e. \. $extraoptions ) ; 57 } /** méthode s i m p l i f i é e pour g é n é r e r un input de type password 61 */ 62 p u b l i c s t a t i c f u n c t i o n addpasswordinput ( $labeltext, $name, $id, $ s i z e, $value= null, $extraoptions= ) { 63 return s e l f : :addinput ( $labeltext, password, $name, $id, $value, s i z e =\. $ s i z e. \. $extraoptions ) ; 64 } /** méthode s i m p l i f i é e pour g é n é r e r un input de type r a d i o 68 */ 69 p u b l i c s t a t i c f u n c t i o n addradioinput ( $labeltext, $name, $id, $checked, $value= null, $extraoptions= ) { 70 return s e l f : :addinput ( $labeltext, r a d i o, $name, $id, $value, ( strcmp ( $checked, checked ) ==0)? checked =\ checked\ :. $extraoptions ) ; 71 }

158 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 73 /** méthode s i m p l i f i é e pour g é n é r e r un input de type r a d i o 75 */ 76 p u b l i c s t a t i c f u n c t i o n addcheckboxinput ( $labeltext, $name, $id, $checked, $value, $extraoptions= ) { 77 return s e l f : :addinput ( $labeltext, checkbox, $name, $id, $value, ( strcmp ( $checked, checked ) ==0)? checked =\ checked\ :. $extraoptions ) ; 78 } /** méthode s i m p l i f i é e pour g é n é r e r un input de type textarea 82 */ 83 p u b l i c s t a t i c f u n c t i o n addtextareainput ( $labeltext, $name, $id, $rows, $ c o l s, $value=null, $extraoptions= ) { 84 $valueoption = ( $value == n u l l )? : $value ; 85 i f ( $extraoptions == n u l l ) { 86 $extraoptions= ; 87 } 88 $returntext.= <p>\n ; 89 i f ( $labeltext!= n u l l && $labeltext!= ) { 90 $returntext.= <l a b e l f o r=\. $id. \ >. $labeltext. </l a b e l >\n ; 91 } 92 $returntext.= <t e x t a r e a name=\. $name. \ id=\. $id. \ rows=\. $rows. \ c o l s =\. $ c o l s. \. $extraoptions. >. $valueoption. </textarea >\n ; 93 $returntext.= </p>\n ; 94 return $returntext ; 95 } /** méthode s i m p l i f i é e pour g é n é r e r un input de type f i l e ( upload ) 99 */ 100 p u b l i c s t a t i c f u n c t i o n adduploadinput ( $labeltext, $name, $id, $ s i z e, $value=, $extraoptions= ) { 101 $valueoption = ( $value == n u l l )? value=\ \ : value=\. $value. \ ; 102 i f ( $extraoptions == n u l l ) { 103 $extraoptions= ; 104 } 105 return s e l f : :addinput ( $labeltext, f i l e, $name, $id, $value, s i z e =\. $ s i z e. \. $valueoption.. $extraoptions ) ; 106 } /** méthode pour commencer un select 110 */ 111 p u b l i c s t a t i c f u n c t i o n b e g i n S e l e c t ( $labeltext, $name, $id, $ m u l t i p l e=f a l s e, $ s i z e =6) { 112 $returntext = ; 113 i f ( $ m u l t i p l e ) 114 $multipleoption= m u l t i p l e=\ multiple\ s i z e =\. $ s i z e. \ ; 115 e l s e 116 $multipleoption= ; 117 i f ( $labeltext!= n u l l && $labeltext!= ) { 118 $returntext.= <p><l a b e l f o r =\. $id. \ >. $labeltext. </l a b e l >\n ; 119 } 120 $returntext.= <s e l e c t name=\. $name. \ id=\. $id. \. $multipleoption. >\n ; 157

159 Rémy Malgouyres, Programmation Web 121 return $returntext ; 122 } /** méthode s i m p l i f i é e pour terminer un select 126 */ 127 p u b l i c s t a t i c f u n c t i o n e n d S e l e c t ( ) { 128 $returntext = </ s e l e c t ></p>\n ; 129 return $returntext ; 130 } /** méthode s i m p l i f i é e pour a j o u t e r une option de select 134 */ 135 p u b l i c s t a t i c f u n c t i o n addselectoption ( $value, $displaytext, $ s e l e c t e d=f a l s e ) { 136 $returntext = ; 137 i f ( $ s e l e c t e d ) 138 $ s e l e c t e d O p t i o n= s e l e c t e d =\ selected \ ; 139 e l s e 140 $ s e l e c t e d O p t i o n= ; 141 $returntext.= <option value=\. $value. \. $ s e l e c t e d O p t i o n. >. $displaytext. </option >\n ; 142 return $returntext ; 143 } /** méthode s i m p l i f i é e pour g é n é r e r un input de type r a d i o 147 */ 148 p u b l i c s t a t i c f u n c t i o n addhiddeninput ( $name, $id, $value, $extraoptions= ) { 149 return s e l f : :addinput (, hidden, $name, $id,. $value, $extraoptions, true ) ; 150 } /** méthode s i m p l i f i é e pour g é n é r e r un bouton submit 154 */ 155 p u b l i c s t a t i c f u n c t i o n addsubmitbutton ( $value= Envoyer, $extraoptions= ) { 156 return s e l f : :addinput ( null, submit,,, $value,. $extraoptions ) ; 157 } 158 } 159?> 7.5 Enchaînement de la saisie à la vue Nous montrons enfin comment enchaîner le filtrage initial, la construction des instances, la détection des erreurs et la génération de la vue HTML qui convient. Nous proposerons aussi de modifier une adresse, en transmettant tous les attributs d une instance dans des champs cachés (hidden). Voici tout d abord la vue permettant de saisir une adresse : exemples/forms2/ex07_vuedefaultformadresse.php 1 <?php 2 require_once ( dirname ( FILE ). / c l a s s e s / VueHtmlUtils. php ) ; 158

160 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 3 require_once ( dirname ( FILE ). / c l a s s e s /AdresseFormView. php ) ; 4 5 echo VueHtmlUtils : :entetehtml5 ( S a i s i e d \ une Adresse, UTF 8, mystyle. css ) ; 6 7 echo AdresseFormView : :getdefaultformhtml ( ex09_receptionadresse. php ) ; 8 9 echo VueHtmlUtils : :finfichierhtml5 ( ) ; 10?> La classe d utilitaires de génération de code HTML, relativement sommaire, est donnée ci-dessous : exemples/forms2/ex08_vuehtmlutils.php 1 <?php 2 class VueHtmlUtils { 3 p u b l i c s t a t i c f u n c t i o n entetehtml5( $ t i t l e, $charset, $css_sheet ) { 4 // s o r t i e du doctype. Les g u i l l e m e t s HTML sont p r o t é g é s par \ 5 $htmlcode = <! doctype html>\n ; 6 $htmlcode.= <html lang=\ f r \ >\n ; 7 $htmlcode.= <head>\n ; 8 $htmlcode.= <meta c h a r s e t=\ ; 9 $htmlcode.= $ c h a r s e t ; 10 $htmlcode.= \ />\n ; 11 $htmlcode.= <l i n k r e l =\ s t y l e s h e e t \ h r e f=\ ; 12 $htmlcode.= $css_sheet ; 13 $htmlcode.= \ />\n ; 14 // concaténation de c h a î n e s de c a r a c t è r e s. 15 $htmlcode.= <t i t l e >. $ t i t l e. </ t i t l e >\n ; 16 $htmlcode.= </head>\n<body>\n ; 17 return $htmlcode ; 159

161 Rémy Malgouyres, Programmation Web 18 } p u b l i c s t a t i c f u n c t i o n finfichierhtml5 ( ) 21 { 22 return </body>\n</html>\n ; 23 } 24 } 25?> Le script qui reçoit les données saisies dans le formulaire, effectue le filtrage pour la sécurité (ici un nettoyage systématique par filter_var), puis construit l instance d adresse et appelle une vue (vue normale ou vue d erreur, selon le cas). exemples/forms2/ex09_receptionadresse.php 1 <?php 2 require_once ( dirname ( FILE ). / c l a s s e s / AdresseFabrique. php ) ; 3 4 r e q u i r e ( ex10_validation. php ) ; 5 6 $ a d r e s s e = AdresseFabrique : :getadresse ( $dataerrors, $id, $numerorue, $rue, 7 $complementadresse, $codepostal, $ v i l l e, $pays ) ; 8 9 i f ( empty ( $dataerrors ) ) { 10 r e q u i r e ( dirname ( FILE ). / ex11_vuenormaleadresse. php ) ; 11 } e l s e { 12 r e q u i r e ( dirname ( FILE ). / ex12_vueerreuradresse. php ) ; 13 } 14?> exemples/forms2/ex10_validation.php 1 <?php 2 $id = i s s e t ($_POST[ id ] )? f i l t e r _ v a r ($_POST[ id ], FILTER_SANITIZE_STRING) : ; 3 $numerorue = i s s e t ($_POST[ numerorue ] )? f i l t e r _ v a r ($_POST[ numerorue ], FILTER_SANITIZE_STRING) : ; 4 $rue = i s s e t ($_POST[ rue ] )? f i l t e r _ v a r ($_POST[ rue ], FILTER_SANITIZE_STRING ) : ; 5 $complementadresse = i s s e t ($_POST[ complementadresse ] )? f i l t e r _ v a r ($_POST[ complementadresse ], FILTER_SANITIZE_STRING) : ; 6 $codepostal = i s s e t ($_POST[ codepostal ] )? f i l t e r _ v a r ($_POST[ codepostal ], FILTER_SANITIZE_STRING) : ; 7 $ v i l l e = i s s e t ($_POST[ v i l l e ] )? f i l t e r _ v a r ($_POST[ v i l l e ], FILTER_SANITIZE_STRING) : ; 8 $pays = i s s e t ($_POST[ pays ] )? f i l t e r _ v a r ($_POST[ pays ], FILTER_SANITIZE_STRING) : ; 9?> 7.6 Les Vues La vue normale affiche simplement l instance d adresse saisie, qui est en principe sans erreurs. exemples/forms2/ex11_vuenormaleadresse.php 160

162 Chapitre 7 : Formulaires PHP/HTML, filtrage, exceptions 1 <?php 2 require_once ( dirname ( FILE ). / c l a s s e s / VueHtmlUtils. php ) ; 3 require_once ( dirname ( FILE ). / c l a s s e s / AdresseView. php ) ; 4 require_once ( dirname ( FILE ). / c l a s s e s /AdresseFormView. php ) ; 5 6 echo VueHtmlUtils : :entetehtml5 ( L\ a d r e s s e a bien é t é s a i s i e, UTF 8, mystyle. css ) ; 7 8 echo AdresseView : :gethtmldevelopped ( $ a d r e s s e ) ; 9 10 echo AdresseFormView : :gethiddenformhtml ( ex13_receptionmodifadresse. php, $adresse, M odifier ) ; echo VueHtmlUtils : :finfichierhtml5 ( ) ; 13?> La vue d erreur affiche un formulaire partiellement rempli avec les données correctes, et affiche le message d erreur (initialement généré dans le setter dee l attribut) pour les données incorrectes. exemples/forms2/ex12_vueerreuradresse.php 1 <?php 2 require_once ( dirname ( FILE ). / c l a s s e s / VueHtmlUtils. php ) ; 3 require_once ( dirname ( FILE ). / c l a s s e s /AdresseFormView. php ) ; 4 5 echo VueHtmlUtils : :entetehtml5 ( S a i s i e d \ une adresse, UTF 8, mystyle. css ) ; 6 7 echo AdresseFormView : :getformerrorshtml ( ex09_receptionadresse. php, 8 $adresse, $dataerrors ) ; 9 10 echo VueHtmlUtils : :finfichierhtml5 ( ) ; 11?> 161

163 Rémy Malgouyres, Programmation Web 7.7 Modification d une Adresse Lors de l affichage de la vue normale de l adresse ci-dessus, un formulaire avec toutes les valeurs des attributs de l adresse sous forme de champs cachés est inclus dans la vue, avec un bouton submit pour éditer les valeurs. On affiche alors une vue normale avec un formulaire pré-rempli pour modifier l adresse. exemples/forms2/ex13_receptionmodifadresse.php 1 <?php 2 require_once ( dirname ( FILE ). / c l a s s e s / AdresseFabrique. php ) ; 3 4 r e q u i r e ( ex10_validation. php ) ; 5 6 $ a d r e s s e = AdresseFabrique : :getadresse ( $dataerrors, $id, $numerorue, $rue, 7 $complementadresse, $codepostal, $ v i l l e, $pays ) ; 8 9 r e q u i r e ( dirname ( FILE ). / ex12_vueerreuradresse. php ) ; 10?> 162

164 Quatrième partie Persistance 163

165 164

166 Table of Contents 8 Cookies Création d un cookie Récupération d un cookie Suppression d un cookie Mise à jour d un cookie Sessions Concept de Session et Problèmes de Sécurité Créer une session Création d une session commune à tous les utilisateurs Durée et SID d une session Destruction d une Session Exemple de Session avec SID aléatoire transmis par GET Exemple de Session avec SID aléatoire transmis par COOKIE Exemple Politique de Sécurité en Matière de Session Bases de Données et PHP Data Objects Créer un Base de Données dans phpmyadmin Création d une Base de Données Relationnelle Créer un Utilisateur MySql Responsable d une BD Initiation à PDO : connexion, query, destruction Établir la Connexion à une Base de Données Parcourir les Résultats d une Requête Requêtes Préparées Classe Singleton de Connexion à une Base de Données

167 166 TABLE OF CONTENTS

168 Introduction : Mécanismes de la Persistence Le protocole HTTP est un protocole sans état. Cela signifie que, dans le protocole HTTP, aucune information n est conservée entre deux transaction. Théoriquement, suivant un tel protocole, il faudrait qu un client qui se reconnecte rerpenne tout depuis le début. Ce comportement peut être problématique pour certaine application, dans lequelles le serveur doit se souvenir des données personnelles du clients, comme son profil, son adresse, etc. Pour cette raison, les développeurs Web doivent implémenter eux meme la persistence, qui permet aux programmes de conserver des données d un connexion à l autre. Il y a trois types de mécanismes permettant d implémenter la persistence : L authentification par login et mot de passe. C est la manière la plus sûre d identifier le client lorsqu il se représente. Cependant, redemander le mot de passe du client à chaque chargement de script pour lui réattribuer ses données peut vite devenir exaspérant pour le client. Il y a généralement nécessité d ajouter un mécanisme de persistence temporaire des données tant que le client passe d une page à l autre au cours d une même visite. Les cookies, qui sont des données (généralement peu volumineuses accessibles dans le tebleau associatif superglobal $_COOKIE) stockées sur la machine du client. Le client a la possibilité de refuser le stockage du cookie, ou d éliminer le cookie entre deux connections. Un pirate a des fois la possibilité de suptiliser un cookie. En général, on ne peut pas se fier de manière sûre au mécanisme des cookies, ce qui n empeche pas d exploiter les cookies. Les cookies sont surtout utilisés pour identifier les client d une connexion à l autre, pour pouvoir lui associer les données venant d une précédente connexion. Pour éviter un piratage des données, l utilisation de cookie doit être accompagnée d une politique de sécurité pour éviter l usurpation d identité. La politique de sécurité, qui dépend de l application considérée, va s appuyer notamment sur : Une date limite de validié du cookie, qui permet de limiter la fenêtre d opportunité pour un pirate. Le hashage ou le chiffrage, qui permet de ne pas révéler en clair les données stokées dans un cookie. Éventuellement l adresse IP du client. Cependant, sachant que les clients mobiles peuvent changer régulièrement d adresse IP, sachant aussi que des adresses IP sur internet peuvent etre partagées par plusieurs clients utilisant la même passerelle, on ne peut pas s appuyer uniquement sur l adresse IP, même si un changement d adresse 167

169 TABLE OF CONTENTS IP peut être l un des critères pour redemander une authentification par mot de passe, surtout en présence d autres indices d une éventuelle usurpation d identité. Des systèmes de jetons aléatoires à usage unique dans le cookie et, d une manière générale, l usage unique des données du cookie, qui permet de limiter la fenêtre d opportunité pour un pirate. En général, il faut trouver un compromis, dépendant de l application, entre le confort du client et la sécurité, et éviter les politiques de sécurité trop bâteau, qu un pirate pourra facilement deviner. Les sessions permettent de stocker des données coté serveur. Les données mémorisées sont des couples clé/valeur (accessibles en PHP dans un tableau associatif superglobal $_SESSION). Pour le stockage sont sous la forme de chaîne de caractère. La sérialisation permet de coder des données complexes (instances de classes, etc.) dans une session. Selon la configuration du serveur, les sessions peuvent etre stockées dans des fichiers sur le disque, dans une base de données, ou encore (généralement sous forme chiffrée) via un cookie sur le poste client. Ces différentes formes de stockage ont un impact sur la charge du serveur, notamment en cas de grosses applications nécessitant que plusieurs serveurs partagent les données de session, et sur la sécurité et la confidentialité des données. Une session, caractérisée par un nom et un identifiant de session (SID), doit etre réattribuée à un client d une page à l autre, et éventuellement d une visite à l autre. Elles sont donc combinées à la transmission de données d un script à l autre, soit par la méthode GET dans l URL, soit par la méthode POST dans un champs caché, soit par un cookie. Les Bases de données, qui permettent de stocker de manière durable de grandes quantités de données, structurées de manière relationnelle. Pour pouvoir associer des données dans une base de données à un client, il faut identifier le client, généralement via une clé primaire dans une table. Cela nécessite de conserver l information de l identité du client par les autres mécanismes (login, cookie, session) ci-dessus. 168

170 Chapitre 8 Cookies 8.1 Création d un cookie On crée un cookie en PHP à l aide de la fonction setcookie. Cette fonction a le prototypes suivant (seul le premier argument est obligatoire) : bool setcookie(string $name, string $value, int $expire = 0, string $path, string $domain, bool $secure = false, bool $httponly = false) Il existe une autre fonction, setrawcookie, de même signature, mais qui n applique pas d encodage URL (voie documentation de la fonction urlencode) aux données du cookie, contrairement à setcookie. bool setrawcookie(string $name, string $value, int $expire = 0, string $path, string $domain, bool $secure = false, bool $httponly = false) La signification des paramètres est la suivante : Name : nom du cookie, qui permet de stocker plusieurs cookies sur un même client avec différentes fonctions. On récupère ensuite les valeurs des cookie grâce au tableau associatif $_COOKIE, qui est indexé par les attributs name des différents cookie. value : La valeur du cookie, qui est stockée sur l ordinateur du client. Ne stockez pas d informations sensibles chez le client, ou alors en chiffrant les données (mais un chiffrement peut toujours se casser...). expire : la date (timestamp Unix : nombre de secondes depuis le 1er janvier 1970 à 0h00) limite de validité du cookie. La fonction time retourne le timestamp de la date actuelle, permettant de fixer la date d expiration en ajoutant un certain nombre de secondes par rapport au présent. La fonction mktime retourne le timestamp d une date donnée par son heure, minute, seconde, année, etc. path : chemin vers le répertoire sur le serveur dans lequel le cookie est disponible dans les scripts PHP (Exemple : / pour la racine du site). La valeur par défaut est le répertoire contenant le script courant définissant le cookie (donné par dirname( FILE ). 169

171 Rémy Malgouyres, Programmation Web secure : permet de ne créer le cookie seulement si la connexion est sécurisé par SSL (protocole https). httponly : lorsqu il vaut true, ce paramètre empêche l accès direct du cookie via des langages de scripts comme javascripts. C est discutable dans la mesure où, par exemple, ça dépend de l implémentation du navigateur client. La fonction setcookie retourne true en cas de succès de création du cookie. Cela ne permet pas d être sur que le cookie a été accepté chez le client. On ne peut pas savoir si le cookie a été accepté avant d avoir chargé un nouveau script essayant d accéder au cookie. On peut éventuellement stocker un tableau de plusieurs chaînes dans un cookie, mais cela crée de fait plusieurs cookies chez le client. Mieux vaut créer un cookie avec un séparateur de son choix (caractère ou patron de type chaîne. Éviter les caractères spéciaux HTML...), puis utiliser le fonction explode, qui va retourner un tableau en coupant la chaîne suivant les occurrences du séparateur. Voici le code de création d un cookie, valable une heure, dans tous les scripts PHP du répertoire courant : exemples/cookies/ex01_setcookie.php 1 <?php 2 // Fonction qui retourne l heure l o c a l e sous fomr de string : 3 f u n c t i o n getlocaltimefrenchformat ( ) { 4 $heurelocalearray = l o c a l t i m e ( time ( ), true ) ; 5 $dayofmonth = str_pad ( i n t v a l ( $heurelocalearray [ tm_mday ], 10), 2, 0, STR_PAD_LEFT) ; 6 $monthofyear = str_pad ( i n t v a l ( $heurelocalearray [ tm_mon ], 10) +1, 2, 0, STR_PAD_LEFT) ; 7 $yearsinceera = str_pad ( i n t v a l ( $heurelocalearray [ tm_year ], 10) +1900, 4, 0,STR_PAD_LEFT) ; 8 $hourofday = str_pad ( i n t v a l ( $heurelocalearray [ tm_hour ], 10), 2, 0, STR_PAD_LEFT) ; 9 $minofhour = str_pad ( i n t v a l ( $heurelocalearray [ tm_min ], 10), 2, 0, STR_PAD_LEFT) ; 10 $secofmin = str_pad ( i n t v a l ( $heurelocalearray [ tm_sec ], 10), 2, 0, STR_PAD_LEFT) ; $heurelocaleformatee = $dayofmonth. /. $monthofyear. /. $yearsinceera 13. à. $hourofday. :. $minofhour. :. $secofmin ; 14 return $heurelocaleformatee ; 15 } 170

172 Chapitre 8 : Cookies // t r o i s chaîne s é p a r é e s par des v i r g u l e s ( c e s t j u s t e un exemple avec explode... ) 18 $valeur = ma chaîne 1, ma chaîne 2, ma chaîne 3,. getlocaltimefrenchformat ( ) ; 19 s e t c o o k i e ( e s s a i C o o k i e, $valeur, time ( ) +3600) ; // Code de l a de l a vue : 22 require_once (. / commonfunctions. php ) ; 23 outputentetehtml5 ( Création d un Cookie, UTF 8, mystyle. css ) ; 24 echo <h1>création d un <i >cookie </i ></h1> ; 25 echo <p><a h r e f=\ ex02_retrievecookie. php\ >Cliquez i c i </a> 26. pour v o i r s i l e <i >cookie </i > a bien é t é s t o c k é chez l e c l i e n t.</p> ; 27 outputfinfichierhtml5 ( ) ; 28?> 8.2 Récupération d un cookie Les cookies peuvent être obtenus, jusqu à expiration, dans le tableau associatif (qui est un superglobal) $_COOKIE. Les clés de ce tableau associatif sont les noms des cookies, et les valeurs du tableau sont les valeurs respectives des cookies. exemples/cookies/ex02_retrievecookie.php 1 <?php 2 i f ( i s s e t ($_COOKIE[ essaicookie ] ) ) { 3 // Le contenu d un c o o k i e d o i t ê t r e f i l t r é comme l e s inputs 4 $valeur = $_COOKIE[ essaicookie ] ; 5 $valeur = f i l t e r _ v a r ( $valeur, FILTER_SANITIZE_STRING) ; 6 $tabchaines = explode (,, $ valeur ) ; 7 } e l s e { 8 $dataerror = array ( cookie => e s s a i C o o k i e i n t r o u v a b l e&nbsp ;! ) ; 9 } // Appel des vues : 12 require_once (. / commonfunctions. php ) ; 13 i f ( empty ( $dataerror ) ) { // Code de l a vue normale : 14 outputentetehtml5 ( Récupération d un Cookie, UTF 8, mystyle. css ) ; 15 echo <h1>récupération d un <i >cookie </i ></h1> ; 16 echo Les c h a î n e s contenues dans l e <i >cookie </i > sont : ; 17 echo <ul> ; 18 f o r e a c h ( $tabchaines as $chaine ) { 19 echo <l i >. $chaine. </ l i l i > ; 20 } 21 echo </ul> ; 22 outputfinfichierhtml5 ( ) ; 23 } e l s e { // Appel de l a vue d e r r e u r : 24 r e q u i r e ( ex02_vueerreur. php ) ; 25 } ?> exemples/cookies/ex02_vueerreur.php 171

173 Rémy Malgouyres, Programmation Web 1 <?php 2 outputentetehtml5 ( Problème de r é c u p é r a t i o n de Cookie, UTF 8, mystyle. css ) ; 3 echo <h1>erreur de r é c u p é r a t i o n de <i >cookie </i ></h1> ; 4 echo <p> ; 5 f o r e a c h ( $dataerror as $ f i e l d => $message ) { 6 echo <i>. $ f i e l d. </i > :. $message. <br/> ; 7 } 8 echo </p> ; 9 outputfinfichierhtml5 ( ) ; 10?> 8.3 Suppression d un cookie Pour supprimer un cookie, on le recrée, avec le même nom, une valeur false (ou chaîne vide), et une date d expiration antérieure au présent. exemples/cookies/ex03_unsetcookie.php 1 <?php 2 // On met une v a l e u r vide et une date d e x p i r a t i o n a n t é r i e u r e au p r é s e n t 3 s e t c o o k i e ( e s s a i C o o k i e,, time ( ) 3600) ; 4 5 // Code de l a vue : 6 require_once (. / commonfunctions. php ) ; 7 outputentetehtml5 ( Suppression d un Cookie, UTF 8, mystyle. css ) ; 8 echo <h1>suppression d un <i >cookie </i ></h1> ; 9 echo <p><a h r e f=\ ex02_retrievecookie. php\ >Cliquez i c i </a> 10. pour v é r i f i e r que l e <i >cookie </i > a bien é t é supprimé chez l e c l i e n t.</p> ; 11 outputfinfichierhtml5 ( ) ; 12?> Le fait de faire unset($_cookie[ essaicookie ]) ne modifiera pas, et ne supprimera pas, le cookie chez le client. 172

174 Chapitre 8 : Cookies 8.4 Mise à jour d un cookie Il n y a pas d autre méthodes pour mettre à jour un cookie que d en créer une nouveau, de même nom, avec la fonction setcookie. On peut par exemple mettre à jour la date d expiration à chaque chargement de page, pour prolonger la validité tant que l utilisateur est actif, sans changer la valeur du cookie : exemples/cookies/ex04_setandprolongcookie.php 1 <?php 2 i f ( i s s e t ($_COOKIE[ essaicookie ] ) ) { // s i l e c o o k i e e x i s t e 3 $valeur = $_COOKIE[ essaicookie ] ; 4 $valeur = f i l t e r _ v a r ( $valeur, FILTER_SANITIZE_STRING) ; 5 } e l s e { // s i l e c o o k i e n e x i s t e pas, on l e c r é e avec l a date : 6 $valeur = Je s u i s l a v a l e u r dans l e c o o k i e :. time ( ) ; 7 } 8 // Le c o o c k i e e s t prolongé tant que l u t i l s a t e u r ne r e s t e pas i n a c t i f 15mn 9 s e t c o o k i e ( e s s a i C o o k i e, $valeur, time ( ) +15*60) ; // Code de l a vue : 12 require_once (. / commonfunctions. php ) ; 13 outputentetehtml5 ( Création d un Cookie, UTF 8, mystyle. css ) ; 14 echo <h1>prolongement de l a V a l i d i t é d un <i >cookie </i ></h1> ; 15 echo <p>valeur courante du c o o k i e : <i >. $ v a l e u r. </i ></p> ; 16 // Lien sur ce même script : 17 echo <p><a h r e f=\. basename ($_SERVER[REQUEST_URI],. php ).. php\ >Cliquez i c i </a> 18. pour v o i r s i l e <i >cookie </i > a bien é t é s t o c k é chez l e c l i e n t.</p> ; 19 outputfinfichierhtml5 ( ) ; 20?> 173

175 Chapitre 9 Sessions 9.1 Concept de Session et Problèmes de Sécurité Les sessions sont des données, mémorisées sur le serveur, qui peuvent rester accessible d un script à l autre. Pour utiliser les sessions en PHP, il faut démarrer la session dans chaque script qui devra utiliser les données ce cette session. Si la session n existe pas, elle sera créée et ne contiendra initialement aucune donnée. Si une session existe et est active, les données de cette session seront chargées dans le tableau associatif superglobal $_SESSION. Ce tableau associatif est aussi accessible en écriture pour ajouter des données en session. Les données de session doivent être sérialisées pour être stockées sur le serveur. La sauvegarde des sessions a un comportement par défaut, qui peut être modifié, sur le serveur. Pour retrouver une session d un script à l autre, un numéro de session (SID) doit être transmis entre les scripts. Il y a trois manières de transmettre le numéro de session, qui doivent chacune s accompagner d une politique de sécurité, pour éviter l usurpation malveillante de l accès à une session. Voici (par ordre décroissant de sécurité supposée) ces trois manières : Les cookies, stockés par le navigateur du client, et éventuellement accessible côté client via un langage de script comme javascript ; La méthode POST, sous la forme d un champs caché de formulaire en clair dans le source HTML ; La méthode GET, en clair dans l URL accessible au client ; Du fait qu il y a toujours une possibilité pour une personne malveillante d accéder aux données transmises, il est généralement déconseillé de transmettre en clair l identifiant de session. Tout au moins, des données doivent permettre de vérifier que l utilisateur qui nous transmet un numéro de session est bien identifié, avant de lui donner accès aux données de session. En effet, les données de session permettent entre autre de maintenir un utilisateur connecté considéré comme authentifié, sans qu il ait besoin de rentrer son mot de passe à chaque chargement de script. En dehors du risque d usurpation d identité lié à la transmission de l identité de l utilisateur ou du numéro de session, les données de session elles mêmes, n étant pas transmises au client, sont relativement sûres (dans la mesure ou le serveur lui-même est sécurisé). 174

176 Chapitre 9 : Sessions 9.2 Créer une session 9.3 Création d une session commune à tous les utilisateurs Voici un exemple de session contenant un compteur du nombre de chargement du script, global pour tous les utilisateurs. Les fonctions utilisées pour la gestion de la session sont : session_id : permet de définir l identifiant (SID) de session (ou d y accéder) ; session_start : permet la création d une session (avec le SID précédemment défini), ou son chargement si la session existe sur le disque et n a pas expiré. session_write_close : Permet d écrire immédiatement la session et de la fermer, permettant éventuellement à d autres scripts de charger la session. (si on n appelle pas explicitement la fonction session_write_close, la session sera quand même écrite (sauf erreur), mais il peut y avoir une latence pour les accès concurrents. exemples/sessions/ex01_createsessionfordummies.php 1 <?php 2 // Création d un i d e n t i f i a n t de s e s s i o n v a l a b l e pour tous l e s u t i l i s a t e u r s 3 s e s s i o n _ i d ( a l l users s e s s i o n ) ; 4 5 // Le démarage de s e s s i o n d o i t a v o i r l i e u avant toute s o r t i e de code HTML via echo, print, e t c. 6 s e s s i o n _ s t a r t ( ) ; 7 8 // Si l a v a r i a b l e de s e s s i o n du j o u r e x i s t e ( i l y a déjà eu un script chargé aujourd hui ) 9 i f ( i s s e t ($_SESSION [ counter ] ) ) { 10 $counter = i n t v a l ($_SESSION [ counter ], 10) ; 11 $counter++ ; 12 $_SESSION [ counter ] =. $counter ; 13 } e l s e { 14 $_SESSION [ counter ] = 1 ; 15 } // Mémorisation de l a donnée de s e s s i o n avant fermeture 175

177 Rémy Malgouyres, Programmation Web 18 $countervalue = $_SESSION [ counter ] ; 19 // Flush des Données de Session, ( sauvegarde immédiate sur l e disque ) 20 // Libère instantanément l e verrou pour l a c c è s à l a s e s s i o n par d a u t r e s s c r i p t s ou c l i e n t s 21 s e s s i o n _ w r i t e _ c l o s e ( ) ; // Code de l a vue : 24 require_once (. / commonfunctions. php ) ; 25 outputentetehtml5 ( U t i l i s a t i o n basique d une s e s s i o n, UTF 8, mystyle. css ) ; 26 echo <h1>u t i l i s a t i o n Basique d une Session <br/>commune à Tous l e s C l i e n t s </ h1> ; 27 echo <p>le s c r i p t a é t é chargé. $countervalue. f o i s depuis l a c r é a t i o n de l a s e s s i o n.</p> ; 28 outputfinfichierhtml5 ( ) ; 29?> 9.4 Durée et SID d une session exemples/sessions/ex02_createsessionbasicid.php 1 <?php 2 require_once (. / commonfunctions. php ) ; 3 4 // On f i x e à 24 heures l a durée de p e r s i s t a n c e de l a s e s s i o n sur l e s e r v e u r 5 // à p a r t i r de chaque connexion 6 session_cache_expire (60*24) ; 7 8 // Création d un i d e n t i f i a n t de s e s s i o n v a l a b l e pour tous l e s u t i l i s a t e u r s 9 s e s s i o n _ i d ( a l l users s e s s i o n ) ; // Le démarage de s e s s i o n d o i t a v o i r l i e u avant toute s o r t i e de code HTML via echo, print, e t c. 12 s e s s i o n _ s t a r t ( ) ; // Chaîne qui code l a date d aujourd hui 15 $heurelocalearray = l o c a l t i m e ( time ( ), true ) ; 16 $dayofmonth = str_pad ( i n t v a l ( $heurelocalearray [ tm_mday ], 10), 2, 0, STR_PAD_LEFT) ; 176

178 Chapitre 9 : Sessions 17 $monthofyear = str_pad ( i n t v a l ( $heurelocalearray [ tm_mon ], 10) +1, 2, 0, STR_PAD_LEFT) ; 18 $yearsinceera = str_pad ( i n t v a l ( $heurelocalearray [ tm_year ], 10) +1900, 4, 0,STR_PAD_LEFT) ; 19 $datesting = $yearsinceera.. $monthofyear.. $dayofmonth ; // Si l a v a r i a b l e de s e s s i o n du j o u r e x i s t e ( i l y a déjà eu un script chargé aujourd hui ) 22 i f ( i s s e t ($_SESSION [ counter. $datesting ] ) ) { 23 $counter = i n t v a l ($_SESSION [ counter. $datesting ], 10) ; 24 $counter++ ; 25 $_SESSION [ counter. $datesting ] =. $counter ; 26 } e l s e { 27 // Chaîne qui code l a date d h i e r 28 $yesterdaylocalearray = l o c a l t i m e ( time ( ) 60*60*24, true ) ; 29 $yestadaydayofmonth = str_pad ( i n t v a l ( $yesterdaylocalearray [ tm_mday ], 10), 2, 0,STR_PAD_LEFT) ; 30 $yestadaymonthofyear = str_pad ( i n t v a l ( $yesterdaylocalearray [ tm_mon ], 10) +1, 2, 0,STR_PAD_LEFT) ; 31 $yestadayyearsinceera = str_pad ( i n t v a l ( $yesterdaylocalearray [ tm_year ], 10) +1900, 4, 0,STR_PAD_LEFT) ; 32 $yesterdaydatestring = $yestadayyearsinceera.. $yestadaymonthofyear.. $yestadaydayofmonth ; 33 // On e f f a c e l e compteur de l a v e i l l e pour é v i t e r que l e s compteurs s accumulent unset ($_SESSION [ counter. $yesterdaydatestring ] ) ; 35 // On i n i t i a l i s e l e compteur du j o u r 36 $_SESSION [ counter. $datesting ] = 1 ; 37 } 38 // Mémorisation de l a donnée de s e s s i o n avant fermeture 39 $countervalue = $_SESSION [ counter. $datesting ] ; 40 // Flush des Données de Session, ( sauvegarde immédiate sur l e disque ) 41 // Libère instantanément l e verrou pour l a c c è s à l a s e s s i o n par d a u t r e s s c r i p t s ou c l i e n t s 42 s e s s i o n _ w r i t e _ c l o s e ( ) ; outputentetehtml5 ( U t i l i s a t i o n basique d une s e s s i o n, UTF 8, mystyle. css ) ; 45 echo <h1>u t i l i s a t i o n d une Session <br/>commune à Tous l e s C l i e n t s </h1> ; echo <p>le s c r i p t a é t é chargé. $countervalue. f o i s aujourd hui ( l e. $dayofmonth. /. $monthofyear. /. $yearsinceera. ).</p> ; 48 outputfinfichierhtml5 ( ) ; 49?> 9.5 Destruction d une Session exemples/sessions/ex03_destroysession.php 1 <?php 2 // Récupération de l a s e s s i o n à l a ide d un i d e n t i f i a n t de s e s s i o n 3 s e s s i o n _ i d ( a l l users s e s s i o n ) ; 4 5 // Le démarage de s e s s i o n d o i t a v o i r l i e u avant toute s o r t i e de code HTML via echo, print, e t c. 177

179 Rémy Malgouyres, Programmation Web 6 s e s s i o n _ s t a r t ( ) ; 7 8 // Détruit t o u t e s l e s v a r i a b l e s de s e s s i o n 9 session_unset ( ) ; 10 // Détruit toute l a s e s s i o n ( a u s s i l e s données préalablement sauvegardées ) 11 s e s s i o n _ d e s t r o y ( ) ; 12?> 9.6 Exemple de Session avec SID aléatoire transmis par GET Voici un exemple qui crée une session spécifique pour chaque utilisateur pour la configuration de sa langue préférée (français ou anglais). Il s agit d une donnée peu sensible, donc l essentiel est de ne pas mélanger les utilisateur. Dans cet exemple, l usurpation d identité n aura pas de conséquences. On ne s intéresse donc pas à la question d un sniffeur qui piraterait l URL passée par GET, permettant au sniffeur d obtenir le SID. exemples/sessions/ex04_sessionrandomidget.php 1 <?php 2 /** Fonction qui retourne un message de bienvenue dans l a langue c h o i s i e */ 3 f u n c t i o n getgreeting ($PREF_LANG) { 4 $htmlgreeting = ; 5 switch ($PREF_LANG) { 6 case en : $htmlgreeting.= Hi, guys, Welcome to <code>mysite. com</ code>&nbsp ;! ; 7 break ; 8 case f r : $htmlgreeting.= Salut l a compagnie, bienvenue sur <code> monsite. f r </code>&nbsp ;! ; 9 break ; d e f a u l t : $htmlgreeting.= Wilkommen, Bienvenue, Welcomme!<br/> ; 12 break ; 13 } 14 return $htmlgreeting ; 15 } $dataerror = array ( ) ; 18 // Test pour v o i r s i l i d e n t i f i a n t de s e s s i o n e x i s t e et s i l a donnée a l a bonne forme 19 // (10 c h i f f r e s hexa e n t r e 0 et f ) 20 i f ( i s s e t ($_GET[ s e s s i o n id ] ) && preg_match ( /^[0 9a fa F]{10} $/, $_GET[ s e s s i o n id ] ) ) { 21 // On a bien v é r i f i é l a forme par e x p r e s s i o n r é g u l i è r e donc, pas d autre précaution 22 $mysid = $_GET[ s e s s i o n id ] ; 23 } e l s e { 24 i f ( i s s e t ($_GET[ s e s s i o n id ] ) ) { 25 $dataerror [ s e s s i o n id ] = I d e n t i f i a n t de s e s s i o n i n c o r r e c t. P i r a t e s s a b s t e n i r... ; 26 } 27 // Génération d un SID par des o c t e t s ( pseudo ) a l é a t o i r e s codés en hexa 28 $cryptostrong = f a l s e ; // Variable pour passage par r é f é r e n c e 178

180 Chapitre 9 : Sessions 29 $ o c t e t s = openssl_random_pseudo_bytes ( 5, $cryptostrong ) ; 30 $mysid = bin2hex ( $ o c t e t s ) ; 31 } 32 s e s s i o n _ i d ( $mysid ) ; // Le démarage de s e s s i o n d o i t a v o i r l i e u avant toute s o r t i e de code HTML via echo, print, e t c. 35 s e s s i o n _ s t a r t ( ) ; // I n i t i a l i s a t i o n des paramètres régionaux // Si un choix de langage e s t p r é c i s é dans l URL, on m o d i f i e l a v a r i a b l e de s e s s i o n 40 i f ( i s s e t ($_GET[ pref_lang ] ) ) { 41 i f ($_GET[ pref_lang ] == en $_GET[ pref_lang ] == f r ) { 42 // Les données e n t r é e s en s e s s i o n doivent ê t r e f i l t r é e s, 43 // même s i, dans ce cas, i l n y a pas de danger car on a t e s t é avec == 44 $_SESSION [ preferred_language ] = f i l t e r _ v a r ($_GET[ pref_lang ], FILTER_SANITIZE_STRING) ; 45 } e l s e { 46 // Paramètre imprévu, on d é t r u i t l a donnée de s e s s i o n, au cas où 47 unset ($_SESSION [ preferred_language ] ) ; 48 } 49 } 50 // Si une p r é f é r e n c e de langage a é t é d é f i n i e, s o i r dans l URL, s o i t en s e s s i o n 51 i f ( i s s e t ($_SESSION [ preferred_language ] ) ) { 52 $PREFERRED_LANG = $_SESSION [ preferred_language ] ; 53 } e l s e { 54 $PREFERRED_LANG = undef ; 55 } // Flush des Données de Session, ( sauvegarde simmédiate ur l e disque ) 58 s e s s i o n _ w r i t e _ c l o s e ( ) ; // Si aucun SID i n c o r r e c t dans l URL 61 require_once (. / commonfunctions. php ) ; 62 i f ( empty ( $dataerror ) ) { // Code de l a vue normale : 63 outputentetehtml5 ( S e s s i o n avec SID A l é a t o i r e, UTF 8, mystyle. css ) ; 64 echo <h1>s e s s i o n avec <i >SID</i > A l é a t o i r e <br/>transmis par <code>get</code ></h1> ; 65 echo <p> ; 66 // Message de bienvenue dans l a langue s é l e c t i o n n é e ou en m u l t i l i n g u e s i undef 67 echo getgreeting ($PREFERRED_LANG). <br/> ; 68 echo <a h r e f=\.$_server[ SCRIPT_NAME ].?s e s s i o n id=. $mysid. &pref_lang= f r \ >Français </a> ou 69. <a h r e f=\.$_server[ SCRIPT_NAME ].?s e s s i o n id=. $mysid. &pref_lang=en \ >English </a> ; 70 echo </p> ; 71 outputfinfichierhtml5 ( ) ; 72 } e l s e { // Appel de l a vue d e r r e u r : 73 r e q u i r e ( ex04_vueerreur. php ) ; 74 }

181 Rémy Malgouyres, Programmation Web 77?> Figure 9.1 : Accueil d un nouveau client (pas de session en cours) Figure 9.2 : Accueil d un client avec langue préférée en anglais Figure 9.3 : Accueil d un client avec SID incorrect 9.7 Exemple de Session avec SID aléatoire transmis par COOKIE Comme dans l exemple précédent, le script crée une session spécifique pour chaque utilisateur pour la configuration de sa langue préférée (français ou anglais). La différence est dans le mode de transmission du SID par cookie. Les données de session sont peu sensibles, donc l usurpation d identité n aura pas de conséquences. On ne s intéresse pas à la question d un vol de cookie qui permettrait à un pirate d obtenir le SID. 1 <?php exemples/sessions/ex05_sessionrandomidcookie.php 180

182 Chapitre 9 : Sessions 2 /** Fonction qui retourne un message de bienvenue dans l a langue c h o i s i e */ 3 f u n c t i o n getgreeting ($PREF_LANG) { 4 $htmlgreeting = ; 5 switch ($PREF_LANG) { 6 case en : $htmlgreeting.= Hi, guys, Welcome to <code>mysite. com</ code>&nbsp ;! ; 7 break ; 8 case f r : $htmlgreeting.= Salut l a compagnie, bienvenue sur <code> monsite. f r </code>&nbsp ;! ; 9 break ; d e f a u l t : $htmlgreeting.= Wilkommen, Bienvenue, Welcomme!<br/> ; 12 break ; 13 } 14 return $htmlgreeting ; 15 } $dataerror = array ( ) ; 18 // Test pour v o i r s i l i d e n t i f i a n t de s e s s i o n e x i s t e et s i l a donnée a l a bonne forme 19 // (10 c h i f f r e s hexa e n t r e 0 et f ) 20 i f ( i s s e t ($_COOKIE[ s e s s i o n id ] ) && preg_match ( /^[0 9a fa F]{10} $/, $_COOKIE[ s e s s i o n id ] ) ) { 21 // On a bien v é r i f i é l a forme par e x p r e s s i o n r é g u l i è r e donc, pas d autre précaution 22 $mysid = $_COOKIE[ s e s s i o n id ] ; 23 } e l s e { 24 i f ( i s s e t ($_COOKIE[ s e s s i o n id ] ) ) { 25 $dataerror [ s e s s i o n id ] = I d e n t i f i a n t de s e s s i o n i n c o r r e c t. P i r a t e s s a b s t e n i r... ; 26 } 27 // Génération d un SID par des o c t e t s ( pseudo ) a l é a t o i r e s codés en hexa 28 $cryptostrong = f a l s e ; // Variable pour passage par r é f é r e n c e 29 $ o c t e t s = openssl_random_pseudo_bytes ( 5, $cryptostrong ) ; 30 $mysid = bin2hex ( $ o c t e t s ) ; 31 } 32 s e s s i o n _ i d ( $mysid ) ; 33 // Création ( ou mise à j o u r ) du c o o k i e. Nouvelle v a l i d i t é du c o o k i e : 10 j o u r s 34 s e t c o o k i e ( s e s s i o n id, $mysid, time ( ) +60*60*24*10) ; // Le démarage de s e s s i o n d o i t a v o i r l i e u avant toute s o r t i e de code HTML via echo, print, e t c. 37 s e s s i o n _ s t a r t ( ) ; // I n i t i a l i s a t i o n des paramètres régionaux // Si un choix de langage e s t p r é c i s é dans l URL, on m o d i f i e l a v a r i a b l e de s e s s i o n 42 i f ( i s s e t ($_GET[ pref_lang ] ) ) { 43 i f ($_GET[ pref_lang ] == en $_GET[ pref_lang ] == f r ) { 44 // Les données e n t r é e s en s e s s i o n doivent ê t r e f i l t r é e s, 45 // même s i, dans ce cas, i l n y a pas de danger car on a t e s t é avec == 46 $_SESSION [ preferred_language ] = h t m l e n t i t i e s ($_GET[ pref_lang ], ENT_QUOTES, UTF 8 ) ; 47 } e l s e { 48 // Paramètre imprévu, on d é t r u i t l a donnée de s e s s i o n, au cas où 181

183 Rémy Malgouyres, Programmation Web 49 unset ($_SESSION [ preferred_language ] ) ; 50 } 51 } 52 // Si une p r é f é r e n c e de langage a é t é d é f i n i e, s o i r dans l URL, s o i t en s e s s i o n 53 i f ( i s s e t ($_SESSION [ preferred_language ] ) ) { 54 $PREFERRED_LANG = $_SESSION [ preferred_language ] ; 55 } e l s e { 56 $PREFERRED_LANG = undef ; 57 } // Flush des Données de Session, ( sauvegarde simmédiate sur l e disque ) 60 s e s s i o n _ w r i t e _ c l o s e ( ) ; require_once (. / commonfunctions. php ) ; 63 i f ( empty ( $dataerror ) ) { // Code de l a vue normale 64 outputentetehtml5 ( S e s s i o n avec SID A l é a t o i r e, UTF 8, mystyle. css ) ; 65 echo <h1>s e s s i o n avec <i >SID</i > A l é a t o i r e <br/>transmis par <code>cookie</ code ></h1> ; 66 echo <p> ; 67 // Message de bienvenue dans l a langue s é l e c t i o n n é e ou en m u l t i l i n g u e s i undef 68 echo getgreeting ($PREFERRED_LANG). <br/> ; 69 echo <a h r e f=\.$_server[ SCRIPT_NAME ].?pref_lang=f r \ >Français </a> ou 70. <a h r e f=\.$_server[ SCRIPT_NAME ].?pref_lang=en\ >English </a> ; 71 echo </p> ; 72 outputfinfichierhtml5 ( ) ; 73 } e l s e { // Appel de l a vue d e r r e u r : 74 r e q u i r e ( ex04_vueerreur. php ) ; 75 } 76?> 9.8 Exemple Politique de Sécurité en Matière de Session Nous voyons maintenant un exemple d utilisation d une session et de cookie un peu mieux sécurisé. Il s agit d un exemple à vocation pédagogique. L auteur décline toute responsabilité en cas d utilisation, telle quelle ou avec adaptation, de cette politique de sécurité. This example is to be taken on an as is basis. We accept no liability for consequences of direct or indirect use of this security policy whatsoever. Le numéro de session (SID) est composé de deux parties concaténées : Une première partie aléatoire ; Une deuxième partie codant l adresse IP du client, ou un hash de celle-ci composé de caractères valides pour un numéro de session. Seule la première partie est envoyée chez le client via un cookie. De plus, le cookie et la session ont une durée de validité de 2mn, temps laissé au client pour charger le script suivant. 182

184 Chapitre 9 : Sessions Lors du chargement du script suivant, la première partie (aléatoire) est récupérée via le cookie. La deuxième partie est calculée par l adresse IP du client. Si les adresses IP ne correspondent pas, la probabilité pour qu on charge par hasard la session, conduisant à une usurpation d identité involontaire, est très faible. Enfin, à chaque chargement de script, on change la partie aléatoire du SID, en copiant les données de session dans une nouvelle, et on re-génère le cookie. exemples/sessions/ex07_authentification.php 1 <?php 2 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 3 require_once ( dirname ( FILE ). / ex06_formpasswdutils. php ) ; 4 outputentetehtml5 ( Login Form, UTF 8, mystyle. css ) ; 5 echo <h1>page d A u t h e n t i f i c a t i o n </h1> ; 6 echo gethtml_loginform ( ) ; 7 outputfinfichierhtml5 ( ) ; 8?> Si le mot de passe est trop simple, on appelle une vue d erreur qui demande un nouveau mot de passe : exemples/sessions/ex07_receivepassword.php 1 <?php 2 require_once ( dirname ( FILE ). / ex06_formpasswdutils. php ) ; 3 4 $wouldbepasswd = $_POST[ motdepasse ] ; 5 6 // Test sur l a forme des données de l o g i n et mot de passe : 7 i f ( empty ( $wouldbepasswd )! isstrongpassword ( $wouldbepasswd ) 183

185 Rémy Malgouyres, Programmation Web 8! f i l t e r _ v a r ($_POST[ ], FILTER_VALIDATE_ ) ) { 9 // Échec de l a u t h e n t i f i c a t i o n : l e s données n ont même pas l a même forme. 10 // S o r t i e du code HTML ( s a i s i e des i d e n t i f i a n t s ) 11 $dataerror [ l o g i n ] = Erreur : l e l o g i n e s t i n c c o r e c t ou mot de passe trop simple ; 12 } e l s e { // l e s données d a u t h e n t i f i c a t i o n ont l a bonne forme. 13 // On v é r i f i e que l e mot de passe ( après hashage SHA512) 14 // e s t bien c e l u i en base de donnée. 15 i f (! userpasswordcheckindatabase ($_POST[ ], hash ( sha512, $wouldbepasswd ) ) ) { 16 // S o r t i e du code HTML ( s a i s i e des i d e n t i f i a n t s ) 17 $dataerror [ l o g i n ] = Erreur : l o g i n ou mot de passe i n c o r r e c t ; 18 } e l s e { 19 // Le numéro de s e s s i o n c o n t i e n t l i n f o r m a t i o n de l a d r e s s e IP 20 // Quelqu un avec une autre a d r e s s e IP ne pourra pas accéder à c e t t e s e s s i o n 21 // suivant notre implémentation ( s a u f à g é n é r e r une c o l i s i o n sur md5 ( Hahaha! ) 22 $mysid = generatesessionidandcookie ($_SERVER[ REMOTE_ADDR ], $mysid_part1 ) ; 23 s e s s i o n _ i d ( $mysid ) ; 24 // Création du c o o k i e avec l a p a r t i e a l é a t o i r e du SID. Nouvelle v a l i d i t é du c o o k i e : 2mn 25 // Un p i r a t e aura besoin de temps pour v o l e r l e c o o k i e. Ça l u i complique l a v i e s e t c o o k i e ( s e s s i o n id part1, $mysid_part1, time ( ) +60*2) ; // L u t i l i s a t e u r v i e n t de s i d e n t i f i e r. Dans l e cas improbable d une c o l l i s i o n sur l e SID, 29 // Mais s u r t o u t d une usurpation d i d e n t i t é, on d é t r u i t l a s e s s i o n 30 // avant de redémarer une s e s s i o n vide 31 s e s s i o n _ s t a r t ( ) ; 32 s e s s i o n _ d e s t r o y ( ) ; 33 // On f i x e à 2mn l a durée de p e r s i s t a n c e de l a s e s s i o n sur l e s e r v e u r 34 // à p a r t i r de chaque connexion. Cela l i m i t e l e temps pour un hackeur 35 // pour deviner l e numéro de s e s s i o n session_cache_expire ( 2 ) ; 37 s e s s i o n _ i d ( $mysid ) ; 38 // Démarrage de l a s e s s i o n 39 s e s s i o n _ s t a r t ( ) ; 40 // On échappe, même s i on s a i t qu on a v a l i d é l a d r e s s e e mail

186 Chapitre 9 : Sessions 41 $_SESSION [ ] = h t m l e n t i t i e s ($_POST[ ], ENT_QUOTES, UTF 8 ) ; 42 $_SESSION [ ip_ address ] = $_SERVER[ REMOTE_ADDR ] ; 43 // Flush des Données de Session, ( sauvegarde simmédiate ur l e disque ) 44 s e s s i o n _ w r i t e _ c l o s e ( ) ; 45 } 46 } require_once ( dirname ( FILE ). / commonfunctions. php ) ; 49 i f ( empty ( $dataerror ) ) { // Code de l a vue normale : 50 outputentetehtml5 ( Welcome Page, UTF 8, mystyle. css ) ; 51 echo <h1>p e r s i s t e n c e d une connexion<br/>exemple de p o l i t i q u e de s é c u r i t é </h1> ; 52 echo Bienvenue! Vous ê t e s convenablement a u t h e n t i f i é.<br/> ; 53 echo Pour accéder encore à des données s e n s i b l e s, 54. <a h r e f=\. / ex08_sessiontestip_randomidcookie. php\ >c l i q u e z i c i </a>. ; 55 outputfinfichierhtml5 ( ) ; 56 } e l s e { // Appel de l a vue d e r r e u r : 57 r e q u i r e ( ex07_vueerreur. php ) ; 58 } 59?> exemples/sessions/ex06_formpasswdutils.php 1 <?php 2 /** Fonction qui t e s t e s i un mot de passe e s t suffisemment d i f f i c i l e */ 3 f u n c t i o n isstrongpassword ( $wouldbepasswd ) { 4 $lengthcondition = ( s t r l e n ( $wouldbepasswd ) >= 8 && s t r l e n ( $wouldbepasswd ) <= 35) ; 5 // On peut sûrement f a i r e plus e f f i c a c e pour l é v a l u a t i o n des e x p r e s s i o n s r é g u l i è r e s... 6 $CharacterDiversityCondition = preg_match ( / [ a z ] /, $wouldbepasswd ) 7 && preg_match ( / [A Z ] /, $wouldbepasswd ) 8 && preg_match ( /[0 9]/, $wouldbepasswd ) 9 && preg_match ( /[\#\ \ \.\@\[\]\=\!\&]/, $wouldbepasswd ) ; 10 return $lengthcondition && $CharacterDiversityCondition ; 11 } /** Fonction qui retourne l e code HTML d un f o r m u l a i r e de l o g i n */ 14 f u n c t i o n gethtml_loginform ( ) { 15 $htmlcode = ; 16 // Test de connexion SSL et l e cas échéant, warning. 17 i f (! i s s e t ($_SERVER[ HTTPS ] ) $_SERVER[ HTTPS ] == o f f ) { 18 $htmlcode.= <p><strong >Warning :</strong > Vous n ê t e s pas sur une connexion s é c u r i s é e <i >HTTPS</i > avec <i >SSL</i >.<br/> 19. Votre c o n f i d e n t i a l i t é n e s t pas g a r a n t i e!!! </p> ; 20 } 21 // Code du f o r m u l a i r e : 22 $htmlcode.= <form method= POST action=. / ex07_receivepassword. php > ; 23 $htmlcode.= <p><label for= e mail >e mail</ label><input type= name= size= 25 /></p> ; 24 $htmlcode.= <p><label for= motdepasse >Mot de passe</ label><input type= password name= motdepasse size= 25 /></p> ; 25 $htmlcode.= <input class= sanslabel value= Envoyer type= submit /> ; 26 $htmlcode.= </form> ; 27 $htmlcode.= <p>l a d r e s s e <i >e mail </i > d o i t ê t r e v a l i d e et 185

187 Rémy Malgouyres, Programmation Web 28. votre mot de passe d o i t c o n t e n i r au moins 8 c a r a c t è r e s, une minuscule, une majuscule, un c h i f f r e, 29. et un c a r a c t è r e parmis. h t m l e n t i t i e s ( #.@[]=!&, ENT_QUOTES, UTF 8 )., merci de votre compréhension... < / p> ; 30 return $htmlcode ; 31 } // f o n c t i o n de g é n é r a t i o n de l ID de s e s s i o n avec 34 // p a r t i e a l é a t o i r e et p a r t i e c o n t r ô l e par a d r e s s e IP 35 f u n c t i o n generatesessionidandcookie ( $ipaddress, &$mysid_part1 ) { 36 // Génération de 5 o c t e t s ( pseudo ) a l é a t o i r e s codés en hexa 37 $cryptostrong = f a l s e ; // Variable pour passage par r é f é r e n c e 38 $ o c t e t s = openssl_random_pseudo_bytes ( 5, $cryptostrong ) ; 39 $mysid_part1 = bin2hex ( $ o c t e t s ) ; // On applique un hash sur l a d r e s s e IP pour é v i t e r l usurpation d i d e n t i t é 42 // Un p i r a t e aura besoin de temps pour d e v i n e r l IP et l usurper, 43 // en devinant a u s s i l a p a r t i e a l é a t o i r e du SID, s u r t o u t avec une connexion SSL $mysid_part2 = hash ( md5, $ipaddress ) ; 45 // Le numéro de s e s s i o n c o n t i e n t l i n f o r m a t i o n de l a d r e s s e IP 46 // Quelqu un avec une autre a d r e s s e IP ne pourra pas accéder à c e t t e s e s s i o n 47 // suivant notre implémentation ( s a u f à g é n é r e r une c o l i s i o n sur md5 ( Hahaha! ) 48 $mysid = $mysid_part1. $mysid_part2 ; 49 return $mysid ; 50 } // Fonction à implémenter : t e s t d e x i s t a n c e du l o g i n /mot de passe en BD 53 f u n c t i o n userpasswordcheckindatabase ( $ , $hashedpassword ) { 54 // TODO : t e s t e r s i l e couple e mail et mot de passe ( après hashage SHA512) 55 // sont bien p r é s e n t s dans l a base de données 56 return true ; 57 } 58?> Si tout se passe bien, on reconstitue bien l ID de session avec contrôle d adresse IP, et on reconnaît l identificateur comme préalablement identifié. exemples/sessions/ex07_receivepassword.php 186

188 Chapitre 9 : Sessions 1 <?php 2 require_once ( dirname ( FILE ). / ex06_formpasswdutils. php ) ; 3 4 $wouldbepasswd = $_POST[ motdepasse ] ; 5 6 // Test sur l a forme des données de l o g i n et mot de passe : 7 i f ( empty ( $wouldbepasswd )! isstrongpassword ( $wouldbepasswd ) 8! f i l t e r _ v a r ($_POST[ ], FILTER_VALIDATE_ ) ) { 9 // Échec de l a u t h e n t i f i c a t i o n : l e s données n ont même pas l a même forme. 10 // S o r t i e du code HTML ( s a i s i e des i d e n t i f i a n t s ) 11 $dataerror [ l o g i n ] = Erreur : l e l o g i n e s t i n c c o r e c t ou mot de passe trop simple ; 12 } e l s e { // l e s données d a u t h e n t i f i c a t i o n ont l a bonne forme. 13 // On v é r i f i e que l e mot de passe ( après hashage SHA512) 14 // e s t bien c e l u i en base de donnée. 15 i f (! userpasswordcheckindatabase ($_POST[ ], hash ( sha512, $wouldbepasswd ) ) ) { 16 // S o r t i e du code HTML ( s a i s i e des i d e n t i f i a n t s ) 17 $dataerror [ l o g i n ] = Erreur : l o g i n ou mot de passe i n c o r r e c t ; 18 } e l s e { 19 // Le numéro de s e s s i o n c o n t i e n t l i n f o r m a t i o n de l a d r e s s e IP 20 // Quelqu un avec une autre a d r e s s e IP ne pourra pas accéder à c e t t e s e s s i o n 21 // suivant notre implémentation ( s a u f à g é n é r e r une c o l i s i o n sur md5 ( Hahaha! ) 22 $mysid = generatesessionidandcookie ($_SERVER[ REMOTE_ADDR ], $mysid_part1 ) ; 23 s e s s i o n _ i d ( $mysid ) ; 24 // Création du c o o k i e avec l a p a r t i e a l é a t o i r e du SID. Nouvelle v a l i d i t é du c o o k i e : 2mn 25 // Un p i r a t e aura besoin de temps pour v o l e r l e c o o k i e. Ça l u i complique l a v i e s e t c o o k i e ( s e s s i o n id part1, $mysid_part1, time ( ) +60*2) ; // L u t i l i s a t e u r v i e n t de s i d e n t i f i e r. Dans l e cas improbable d une c o l l i s i o n sur l e SID, 29 // Mais s u r t o u t d une usurpation d i d e n t i t é, on d é t r u i t l a s e s s i o n 30 // avant de redémarer une s e s s i o n vide 31 s e s s i o n _ s t a r t ( ) ; 32 s e s s i o n _ d e s t r o y ( ) ; 33 // On f i x e à 2mn l a durée de p e r s i s t a n c e de l a s e s s i o n sur l e s e r v e u r 34 // à p a r t i r de chaque connexion. Cela l i m i t e l e temps pour un hackeur 35 // pour deviner l e numéro de s e s s i o n session_cache_expire ( 2 ) ; 37 s e s s i o n _ i d ( $mysid ) ; 38 // Démarrage de l a s e s s i o n 39 s e s s i o n _ s t a r t ( ) ; 40 // On échappe, même s i on s a i t qu on a v a l i d é l a d r e s s e e mail $_SESSION [ ] = h t m l e n t i t i e s ($_POST[ ], ENT_QUOTES, UTF 8 ) ; 42 $_SESSION [ ip_ address ] = $_SERVER[ REMOTE_ADDR ] ; 43 // Flush des Données de Session, ( sauvegarde simmédiate ur l e disque ) 44 s e s s i o n _ w r i t e _ c l o s e ( ) ; 45 } 46 } require_once ( dirname ( FILE ). / commonfunctions. php ) ; 187

189 Rémy Malgouyres, Programmation Web 49 i f ( empty ( $dataerror ) ) { // Code de l a vue normale : 50 outputentetehtml5 ( Welcome Page, UTF 8, mystyle. css ) ; 51 echo <h1>p e r s i s t e n c e d une connexion<br/>exemple de p o l i t i q u e de s é c u r i t é </h1> ; 52 echo Bienvenue! Vous ê t e s convenablement a u t h e n t i f i é.<br/> ; 53 echo Pour accéder encore à des données s e n s i b l e s, 54. <a h r e f=\. / ex08_sessiontestip_randomidcookie. php\ >c l i q u e z i c i </a>. ; 55 outputfinfichierhtml5 ( ) ; 56 } e l s e { // Appel de l a vue d e r r e u r : 57 r e q u i r e ( ex07_vueerreur. php ) ; 58 } 59?> Lorsque l utilisateur poursuit la navigation, il reste reconnu et peut accéder à ses données personnelles : exemples/sessions/ex08_sessiontestip_randomidcookie.php 1 <?php 2 require_once ( dirname ( FILE ). / ex06_formpasswdutils. php ) ; 3 4 $dataerror = array ( ) ; 5 // Test pour v o i r s i l i d e n t i f i a n t de s e s s i o n e x i s t e et s i l a donnée a l a bonne forme 6 // (10 c h i f f r e s hexa e n t r e 0 et f ) 7 i f (! i s s e t ($_COOKIE[ s e s s i o n id part1 ] ) 8! preg_match ( /^[0 9a fa F]{10} $/, $_COOKIE[ s e s s i o n id part1 ] ) ) { 9 $dataerror [ no cookie ] = Votre c o o k i e a peut ê t r e expirée, 10. Merci de vous connecter à nouveau... ; 11 } e l s e { 12 // On a bien v é r i f i é l a forme par e x p r e s s i o n r é g u l i è r e donc, pas d autre précaution 13 $mysid_part1 = $_COOKIE[ s e s s i o n id part1 ] ; 188

190 Chapitre 9 : Sessions 14 // On applique l e même hash sur l a d r e s s e IP que l o r s de l a c r é a t i o n i n i t i a l e de l a s e s s i o n 15 // pour r e t r o u v e r notre numéro de s e s s i o n i n i t i a l. 16 $mysid_part2 = hash ( md5, $_SERVER[ REMOTE_ADDR ] ) ; 17 // On r e c o n s t i t u e l e SID complet : 18 $mysid = $mysid_part1. $mysid_part2 ; 19 // On r écupère l e s données de s e s s i o n : 20 s e s s i o n _ i d ( $mysid ) ; 21 // Le démarage de s e s s i o n d o i t a v o i r l i e u avant toute s o r t i e de code HTML via echo, print, e t c. 22 s e s s i o n _ s t a r t ( ) ; 23 // Prolongement de l a v a l i d i t é du c o o k i e. Nouvelle v a l i d i t é du c o o k i e : 2mn 24 s e t c o o k i e ( s e s s i o n id part1, $mysid_part1, time ( ) +60*2) ; 25 i f ( empty ($_SESSION [ ] ) ) { 26 $dataerror [ no s e s s i o n ] = Votre s e s s i o n a peut ê t r e expirée, 27. Merci de vous connecter à nouveau... ; 28 s e s s i o n _ d e s t r o y ( ) ; 29 } e l s e { 30 // Raffinement : on change l a p a r t i e a l é a t o i r e du SID, en copiant 31 // l a s e s s i o n dans une n o u v e l l e. On r e g é n è r e e n s u i t e l e c o o k i e 32 // Comme ça, l e c o o k i e n e s t v a l a b l e qu une f o i s, et l ID de s e s s i o n a u s s i 33 // ce qui l i m i t e beaucoup l a p o s s i b i l i t é d un é v e n t u e l hacker 34 $backupsession_ = $_SESSION [ ] ; 35 // On d é t r u i t l ancienne s e s s i o n 36 s e s s i o n _ d e s t r o y ( ) ; 37 $mysid = generatesessionidandcookie ($_SERVER[ REMOTE_ADDR ], $mysid_part1 ) ; 38 s e s s i o n _ i d ( $mysid ) ; 39 // Création du c o o k i e avec l a p a r t i e a l é a t o i r e du SID. V a l i d i t é du c o o k i e : 2mn 40 // Un p i r a t e aura besoin de temps pour v o l e r l e c o o k i e. Ça l u i complique l a v i e // D autant qu on c r é e un c o o k i e tout neuf à chaque chargement de script s e t c o o k i e ( s e s s i o n id part1, $mysid_part1, time ( ) +60*2) ; 43 s e s s i o n _ s t a r t ( ) ; 44 $_SESSION [ ] = $backupsession_ ; 45 // Flush des Données de Session, ( sauvegarde simmédiate ur l e disque ) 46 s e s s i o n _ w r i t e _ c l o s e ( ) ; 47 } 48 } require_once ( dirname ( FILE ). / commonfunctions. php ) ; 51 i f ( empty ( $dataerror ) ) { // Code de l a vue normale 52 outputentetehtml5 ( Consultation des Données P e r s o n n e l l e s, UTF 8, mystyle. css ) ; 53 echo <h1>consultation des Données P e r s o n n e l l e s </h1> ; 54 echo <p> ; 55 echo Ne l e d i t e à personne : l e <i >SID</i > e s t : <br/>. $mysid ; 56 echo </p><p> ; 57 echo Votre a d r e s s e e mail e s t :. $_SESSION [ ]. <br/> ; 58 echo Grâce à votre a d r e s s e e mail, l e s e r v e u r peur r e t r o u v e r vos données p e r s o n n e l l e s <br/> ; 59 echo et vous l e s a f f i c h e r. Et d a i l l e u r s, l e s v o i c i... < br/> ; 60 echo Pour accéder encore à des données s e n s i b l e s, 61. <a h r e f=\. / ex08_sessiontestip_randomidcookie. php\ >c l i q u e z i c i </a>. 189

191 Rémy Malgouyres, Programmation Web ; 62 echo </p> ; 63 outputfinfichierhtml5 ( ) ; 64 } e l s e { // Appel de l a vue d e r r e u r : 65 r e q u i r e ( ex07_vueerreur. php ) ; 66 } 67?> Figure 9.4 : Re-chargement du script. La connexion persiste, mais le SID a changé. Figure 9.5 : Re-chargement du script. Expiration du cookie. 190

192 Chapitre 10 Bases de Données et PHP Data Objects 10.1 Créer un Base de Données dans phpmyadmin Création d une Base de Données Relationnelle Figure 10.1 : Création d une nouvelle base de données Figure 10.2 : Création d une nouvelle table 191

193 Rémy Malgouyres, Programmation Web Figure 10.3 : Exemple de base de données avec deux tables Figure 10.4 : Vue Relationnelle de base de données avec deux tables Créer un Utilisateur MySql Responsable d une BD Pour éviter qu un éventuel piratage de la configuration de l authentification pour l accès aux bases de données, qui se trouve en clair dans les sources PHP, ne donnée accès à toutes les bases de données, nous pratiquons des droits étanches entre nos différentes bases de données. Dans notre cas, l utilisateur remy aura les droits uniquement sur la base ExampleDataBase. Figure 10.5 : Ajout d un Utilisateur MySQL 192

194 Chapitre 10 : Bases de Données et PHP Data Objects Figure 10.6 : Accès de l Utilisateur MySQL Uniquement sur le Serveur Local Figure 10.7 : Ajout de Privilèges Spécifiques d un Utilisateur sur une Base de Données 193

195 Rémy Malgouyres, Programmation Web Figure 10.8 : Exemple : Donner tous les Droits à l Utilisateur sur une Base 194

196 Chapitre 10 : Bases de Données et PHP Data Objects 10.2 Initiation à PDO : connexion, query, destruction L extension du langage PHP appelée PHP Data Objects fournit une couche d abstraction pour accéder à des données, à l aide de différents drivers. Comme exemples de drivers, on peut citer MySQL, Oracle, SQLite, PostgreSQL, MS SQL Sever, etc. L intérêt de PDO est de permettre d utiliser tous ces drivers, qui accèdent à des bases de données différentes, avec les mêmes fonction : les méthodes de PDO Établir la Connexion à une Base de Données La connexion à la base de données se fait avec le nom du driver (ici mysql), le nom d hôte, le nom de la base de données, le nom d utilisateur ayant les droits sur la base de données, et son mot de passe. Une éventuelle exception issue du constructeur de PDO doit absolument être gérée avec try...catch (ou avec un handler), car sinon le message de l exception s affiche, révélant le nom et le mot de passe de l utilisateur ayant les droits sur la base. exemples/pdo/ex01_connexionpdo.php 1 <?php 2 $mysqluser = remy ; 3 $mysqlpassword = my_password ; 4 $database = ExampleDataBase ; 5 6 $dataerror = array ( ) ; 7 8 // ON DOIT ABSOLUMENT GÉRER CETTE EXCEPTION, FAUTE DE QUOI 9 // L UTILISATEUR DE LA BASE DE DONNÉES ET LE MOT DE PASSE 10 // APPARAÎSSENT EN CLAIR!!!! 11 try { 12 // Création de l i n s t a n c e de PDO ( database handler ). 13 $dbh = new PDO( mysql :host=l o c a l h o s t ; dbname=. $database, $mysqluser, $mysqlpassword ) ; 14 } catch ( PDOException $e ) { 15 $dataerror [ connection ] = Erreur de connexion à l a base de données. 16. Vous n avez pas besoin d en s a v o i r plus... ; 17 r e q u i r e ( vueerreur. php ) ; 18 d i e ( ) ; 19 } 20 // Requête : chaîne de c a r a c t è r e s contenant une r e q u ê t e v a l i d e en SQL 21 $requete = INSERT INTO Adresse ( id, numerorue, rue, complementadresse, codepostal, v i l l e, pays ) 195

197 Rémy Malgouyres, Programmation Web 22. VALUES ( abea, 11, A l l é e des Pies Jaunes, Bâtiment 2D, 63000, Clermont Ferrand, France ) ; // Exécution de l a r equête et mémorisation du r é s u l t a t : 25 $ r e s u l t E x e c = $dbh >exec ( $requete ) ; i f ( $ r e s u l t E x e c === f a l s e ) { 28 $dataerror [ r equete ] = Problème d e x é c u t i o n de l a r e q u ê t e. 29. ( par exemple, une l i g n e avec c e t t e c l é p r i m a i r e e x i s t e déjà, 30. ou encore l a requête n e s t pas une r e q u ê t e v a l i d e sur l a base en q u e s t i o n... ) ; 31 r e q u i r e ( vueerreur. php ) ; 32 d i e ( ) ; 33 } // $ r e s u l t E x e c d o i t donner l e nombre de l i g n e s a f f e c t é e s ( i n s é r é e s en l occurence ) 36 i f ( $ r e s u l t E x e c === 0) { 37 $dataerror [ r equete ] = Problème d e x é c u t i o n de l a requête, Aucune l i g n e n a é t é a f f e c t é e par l a r equête. ; 38 r e q u i r e ( vueerreur. php ) ; 39 d i e ( ) ; 40 } // Fermeture de l a connexion ( connexion non p e r s i s t a n t e ) 43 $ r e s u l t E x e c = n u l l ; 44 $dbh = n u l l ; // Code de l a vue : 47 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 48 outputentetehtml5 ( Ma Première Connexion PDO, UTF 8, mystyle. css ) ; 49 echo <h1>i n i t i e r une Connexion <i >PDO</i ></h1> ; 50 echo La requête a bien é t é exécutée... ; 51 outputfinfichierhtml5 ( ) ; 52?> exemples/pdo/ex01_vueerreur.php 1 <?php 2 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 3 outputentetehtml5 ( Erreur BD, UTF 8, mystyle. css ) ; 4 echo <h1>une e r r e u r s e s t produite </h1> ; 5 f o r e a c h ( $dataerror as $errormsg ) { 196

198 Chapitre 10 : Bases de Données et PHP Data Objects 6 echo <p>. $errormsg. </p> ; 7 } 8 outputfinfichierhtml5 ( ) ; 9?> Figure 10.9 : Cas où la clé primaire existe déjà (ici : rechargement du script) Voici un exemple où l exception générée par le constructeur de PDO n est pas gérée. Les données d authentification pour l accès à la base de données apparaîssent en clair chez le client. exemples/pdo/ex02_withnotrycatchleakproblem.php 1 <?php 2 $mysqluser = remy ; 3 $mysqlpassword = my_password ; 4 $database = ExampleMisSpelledDataBase ; 197

199 Rémy Malgouyres, Programmation Web 5 6 $dbh = new PDO( mysql :host=l o c a l h o s t ; dbname=. $database, $mysqluser, $mysqlpassword ) ; 7 8 $requete = INSERT INTO Adresse ( id, numerorue, rue, complementadresse, codepostal, v i l l e, pays ) 9. VALUES ( 0 fda5a80a, 11, A l l é e des Pies Jaunes, Bâtiment 2D, 63000, Clermont Ferrand, France ) ; 10 $dbh >query ( $requete ) ; require_once ( dirname ( FILE ). / commonfunctions. php ) ; 13 outputentetehtml5 ( Ma Première Connexion PDO, UTF 8, mystyle. css ) ; 14 // Code de l a vue : 15 f o r e a c h ( $dbh >query ( SELECT * from Adresse ) as $row ) { 16 print_r ( $row ) ; 17 } 18 $dbh = n u l l ; 19 outputfinfichierhtml5 ( ) ; 20?> Dans les exemples des deux parties suivantes, nous incluerons (par un require) le fichier suivant qui réalisera la connexion à la base de données : exemples/pdo/ex03_connecttodatabasepdo.php 1 <?php 2 $mysqluser = remy ; 3 $mysqlpassword = my_password ; 4 $database = ExampleDataBase ; 5 6 // ON DOIT ABSOLUMENT GÉRER CETTE EXCEPTION, FAUTE DE QUOI 7 // L UTILISATEUR DE LA BASE DE DONNÉES ET LE MOT DE PASSE 8 // APPARAÎSSENT EN CLAIR!!!! 9 try { 10 // Création de l i n s t a n c e de PDO ( database handler ). 11 $dbh = new PDO( mysql :host=l o c a l h o s t ; dbname=. $database, $mysqluser, $mysqlpassword ) ; 12 } catch ( PDOException $e ) { 13 $dataerror [ connexion bd ] = Erreur de connexion à l a base de données. 14. Vous n avez pas besoin d en s a v o i r plus... ; 15 r e q u i r e ( vueerreur. php ) ; 16 d i e ( ) ; 17 } 18?> Parcourir les Résultats d une Requête Voici un exemple qui récupère les lignes des résultats d une requête (de type SELECT) sous une forme associative. Les clés du tableau associatif, pour chaque ligne, sont les noms de colonnes du résultat de la requête. exemples/pdo/ex03_queryforeachmodeassoc.php 1 <?php 2 // Connexion à l a base de données : 3 require_once ( dirname ( FILE ). / ex03_connecttodatabasepdo. php ) ; 198

200 Chapitre 10 : Bases de Données et PHP Data Objects 4 5 // Stockage des données r é s u l t a t de l a r e q u ê t e dans une v a r i a b l e 6 // De type PDOStatement 7 $statement = $dbh >query ( SELECT * from Adresse ) ; 8 // On veut r é c u p é r e r l e s l i g n e s comme des tableaux A s s o c i a t i f s 9 $statement >setfetchmode (PDO : :FETCH_ASSOC) ; require_once ( dirname ( FILE ). / commonfunctions. php ) ; 12 outputentetehtml5 ( P a r c o u r i r l e s R é s u l t a t s d une Requête, UTF 8, mystyle. css ) ; echo <h1>p a r c o u r i r l e s R é s u l t a t s d une Requête</h1> ; echo <p>le r é s u l t a t de l a r equête possède. $statement >columncount ( ). colonnes.</p> ; echo <p> ; 19 echo <strong >U t i l i s a t i o n comme tableau a s s o c i a t i f :</strong > ; 20 echo </p> ; 21 f o r e a c h ( $statement as $row ) { 22 echo <p> ; 23 echo $row [ numerorue ].,. $row [ rue ]., ; 24 i f (! empty ( $row [ complementadresse ] ) ) 25 echo $row [ complementadresse ]., ; 26 echo $row [ codepostal ]. ; 27 echo $row [ v i l l e ]. ; 28 echo $row [ pays ] ; 29 echo </p> ; 30 } // Connexion non p e r s i s t a n t e : on ferme l a connexion 33 // i l f a u t d é t r u i r e tous l e s o b j e c t s l i é s à l a connexion SANS EN OUBLIER 34 // ( en l e s mettant à null, pour que l a connexion se ferme ). 35 $statement = n u l l ; 36 $dbh = n u l l ;

201 Rémy Malgouyres, Programmation Web 38 outputfinfichierhtml5 ( ) ; 39?> Voici un exemple qui récupère les lignes des résultats d une requête (de type SELECT) sous une forme soit associative, soit numérique. Les clés du tableau associatif, pour chaque ligne, sont les noms de colonnes du résultat de la requête. Les clés du tableau numérique, pour chaque ligne, sont les numéros de colonnes du résultat de la requête (commençant à 0). exemples/pdo/ex04_fetchall_fetchmodeboth.php 1 <?php 2 // Connexion à l a base de données : 3 require_once ( dirname ( FILE ). / ex03_connecttodatabasepdo. php ) ; 4 5 // Stockage des données r é s u l t a t de l a r e q u ê t e dans une v a r i a b l e 6 // De type PDOStatement 7 $statement = $dbh >query ( SELECT * from Adresse ) ; 8 i f ( $statement === f a l s e ) { 9 $dataerror [ query ] = Problème d e x é c u t i o n de l a r e q u ê t e. 10. ( par exemple, l a connexion n e s t pas ouverte ou l a t a b l e n e x i s t e pas... ) ; 11 d i e ( ) ; 12 } $statement >setfetchmode (PDO : :FETCH_BOTH) ; // Pour pouvoir p a r c o u r i r t r o i s f o i s l e s r é s u l t a t s, on c o p i e ceux c i 17 // dans un grand tableau. 18 // Ça peut u t i l i s e r beaucoup de mémoire s i l y a beaucoup de l i g n e s

202 Chapitre 10 : Bases de Données et PHP Data Objects 19 $ t a b R e s u l t a t s = $statement >f e t c h A l l ( ) ; // Code de l a vue : 22 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 23 outputentetehtml5 ( P a r c o u r i r l e s R é s u l t a t s d une Requête, UTF 8, mystyle. css ) ; 24 echo <h1>p a r c o u r i r l e s R é s u l t a t s d une Requête ( 2 )</h1> ; 25 echo <p> ; 26 echo <strong >A f f i c h a g e brut de chaque l i g n e </strong > ; 27 echo </p> ; f o r e a c h ( $ t a b R e s u l t a t s as $row ) { 30 echo <p> ; 31 print_r ( $row ). <br/><br/> ; 32 echo </p> ; 33 } echo <p> ; 36 echo <strong >U t i l i s a t i o n comme tableau a s s o c i a t i f :</strong > ; 37 echo </p> ; 38 f o r e a c h ( $ t a b R e s u l t a t s as $row ) { 39 echo <p> ; 40 echo $row [ numerorue ].,. $row [ rue ]., ; 41 i f (! empty ( $row [ complementadresse ] ) ) 42 echo $row [ complementadresse ]., ; 43 echo $row [ codepostal ]. ; 44 echo $row [ v i l l e ]. ; 45 echo $row [ pays ] ; 46 echo </p> ; 47 } 48 echo </p> ; echo <p> ; 51 echo <strong >U t i l i s a t i o n comme tableau numérique :</strong > ; 52 echo </p> ; 53 f o r e a c h ( $ t a b R e s u l t a t s as $row ) { 54 echo <p>( ; 55 f o r ( $ i = 1 ; $ i < $statement >columncount ( ) ; $ i++){ 56 i f ( $i >1){ 57 echo, ; 58 } 59 echo $row [ $ i ] ; 60 } 61 echo )</p> ; 62 } 63 outputfinfichierhtml5 ( ) ; // Connexion non p e r s i s t a n t e : on ferme l a connexion 66 // i l f a u t d é t r u i r e tous l e s o b j e c t s l i é s à l a connexion SANS EN OUBLIER 67 // ( en l e s mettant à null, pour que l a connexion de ferme. 68 $statement = n u l l ; 69 $dbh = n u l l ; 70?> D une manière générale, les méthodes fetch (renvoie une seule ligne des résultats d une requête) et fetchall (renvoie toutes les lignes des résultats d une requête) ont des options sur 201

203 Rémy Malgouyres, Programmation Web la structure des données retournées. Une liste (non exaustive!!!) de ces options est : PDO :: FETCH_ASSOC : lignes sous forme d un tableau associatif indexé par le nom de la colonne ; PDO :: FETCH_BOTH : lignes sous forme d un tableau à la fois associatif indexé par le nom de la colonne et numérique indexé par le numéro de la colonne ; PDO :: FETCH_OBJ : lignes sous la forme d objets anonymes dont les propriétés sont les noms de la colonne ; 10.3 Requêtes Préparées L idée des requêtes préparées est la suivante : 1. On indique à PDO la requête SQL, sauf que les valeurs (attributs des tables...) ne sont pas précisées (ce sont des?). 2. Cela permet déjà à PDO d analyser une fois pour toute la requête, même si on doit exécuter la requête plusieurs fois avec des valeurs différentes. C est ce qu on appelle préparer la requête. Cela améliore généralement l efficacité, réduisant la charge du serveur et les délais d exécution des requêtes. 3. Avant d exécuter la requête préparée, ou au moment de l exécution de la requête préparée, on spécifie les valeurs (attributs des tables...) qui viennent remplace les? dans la requête. Ces valeurs, qui peuvent correspondre à des inputs utilisateur, sont automatiquement filtrée, évitant tout risque d injection SQL. Le mécanisme des requêtes préparées repose sur un lien effectué (avec la méthode bindparam) entre une variable PHP (donnée par sa référence), et une valeur non fixée (?) dans la requête. Il peut y avoir plusieurs syntaxes pour les requêtes préparées. Nous en voyons une. Voyons déjà un exemple d insertion d une adresse dans une table. L adresse est saisie dans un formulaire : exemples/pdo/ex05_formadresse.php 1 <! doctype html> 2 <html lang= f r > 3 <head> 4 <meta charset= UTF 8 /> 5 <link rel= s t y l e s h e e t href=. / mystyle. c s s /> 6 <t i t l e>s a i s i e d une Adresse</ t i t l e> 7 </head> 8 <body> 9 <h1>s a i s i e d une a d r e s s e</h1> 10 <form method= post action= ex07_requetespreparees. php > 11 <p> 12 <label for= numerorue >Numéro</ label> 13 <input type= t e x t name= numerorue id= numerorue size= 4 /><br/> 14 </p> 15 <p> 16 <label for= rue >Place /Rue*</ label> 17 <input type= t e x t name= rue id= numerorue size= 30 /> 202

204 Chapitre 10 : Bases de Données et PHP Data Objects 18 </p> <p> 21 <label for= complementadresse >Complément d a d r e s s e</ label> 22 <input type= t e x t name= complementadresse id= complementadresse s i z e= 30 /> <br/> 23 </p> 24 <p> 25 <label for= codepostal >Code p o s t a l *</ label> 26 <input type= t e x t name= codepostal id= codepostal size= 10 /><br/> 27 </p> 28 <p> 29 <label for= v i l l e >V i l l e *</ label> 30 <input type= t e x t name= v i l l e id= v i l l e size= 10 /><br/> 31 </p> 32 <p> 33 <input type= submit value= Envoyer class= sanslabel ></input> 34 </p> 35 </form> 36 </body> 37 </html> Les valeurs saisies par l utilsateur seront récupérées du tableau $_POST dans un fichier PHP, qui sera inclus par un require juste avant d exécuter la requête de type INSERT : exemples/pdo/ex06_retrieveinputposts.php 1 <?php 2 $numerorue= ; 3 i f ( i s s e t ($_POST[ numerorue ] ) ) { 4 $numerorue = f i l t e r _ v a r ($_POST[ numerorue ], FILTER_SANITIZE_STRING) ; 5 } 6 7 $rue= ; 8 i f ( i s s e t ($_POST[ rue ] ) ) { 9 $rue = f i l t e r _ v a r ($_POST[ rue ], FILTER_SANITIZE_STRING) ; 10 } $complementadresse= ; 13 i f ( i s s e t ($_POST[ complementadresse ] ) ) { 14 $complementadresse = f i l t e r _ v a r ($_POST[ complementadresse ], FILTER_SANITIZE_STRING) ; 15 } 16 $codepostal= ; 17 i f ( i s s e t ($_POST[ codepostal ] ) ) { 18 $codepostal = f i l t e r _ v a r ($_POST[ codepostal ], FILTER_SANITIZE_STRING) ; 19 } 20 $ v i l l e= ; 21 i f ( i s s e t ($_POST[ v i l l e ] ) ) { 22 $ v i l l e = f i l t e r _ v a r ($_POST[ v i l l e ], FILTER_SANITIZE_STRING) ; 23 } 24 $pays= France ; 25 i f ( i s s e t ($_POST[ pays ] ) && $_POST[ pays ]!= ) { 26 $pays = f i l t e r _ v a r ($_POST[ pays ], FILTER_SANITIZE_STRING) ; 27 } 28?> 203

205 Rémy Malgouyres, Programmation Web Voici enfin l exemple qui effectue : 1. La préparation de la requête de type INSERT (avec des? à la place des attributs de l adresse) ; 2. Définit (avec bindvalue) le lien entre les? et des variables PHP ; 3. Exécute la requête (en effectuant les tests d erreur). exemples/pdo/ex07_requetespreparees.php 1 <?php 2 // Connexion à l a base de données 3 require_once ( dirname ( FILE ). / ex03_connecttodatabasepdo. php ) ; 4 5 // Préparation de l a r equête ( chaîne r e p r é s e n t a n t une r e q u ê t e SQL 6 // s a u f que l e s v a l e u r s à i n s é r e r dont des?) 7 $statement = $dbh >prepare ( INSERT INTO Adresse ( id, numerorue, rue, complementadresse, codepostal, v i l l e, pays ) 8. VALUES (?,?,?,?,?,?,?) ) ; 9 10 // Test d e r r e u r en supposant l e mode de g e s t i o n des e r r e u r s PDO : : ERRMODE_SILENT 11 // ( sinon, avec l e mode PDO : :ERRMODE_EXCEPTION i l f a u d r a i t u t i l i s e r avec try... catch ) 12 i f ( $statement === f a l s e ) { 13 $dataerror [ preparation query ] = Problème l o r s de l a p r é p a r a t i o n de l a requête. 14. ( par exemple, l a syntaxe de l a r e q u ê t e e s t i n v a l i d e 15. pour l e d r i v e r u t i l i s é... ) ; 16 r e q u i r e ( vueerreur. php ) ; 17 d i e ( ) ; 18 } // L i a i s o n de v a r i a b l e s avec l e s? de l a r e q u ê t e préparée : 21 // Le premier paramètre de bindparam e s t i c i l e numéro du? 22 // en commençant par // Lors de l e x é c u t i o n de l a requête, chaque? s e r a remplacé par 24 // l e contenu de l a v a r i a b l e correspondante. 25 $statement >bindparam ( 1, $id ) ; 26 $statement >bindparam ( 2, $numerorue ) ; 27 $statement >bindparam ( 3, $rue ) ; 28 $statement >bindparam ( 4, $complementadresse ) ; 29 $statement >bindparam ( 5, $codepostal ) ; 30 $statement >bindparam ( 6, $ v i l l e ) ; 31 $statement >bindparam ( 7, $pays ) ; // Récupération des données du f o r m u l a i r e s et a f f e c t a t i o n des v a r i a b l e s 34 // $numerorue, $rue, $complementadresse, $codepostal, $ v i l l e, $pays 35 // à p a r t i r des données u t i l i s a t e u r ( tableau $_POST) 36 r e q u i r e ( dirname ( FILE ). / ex06_retrieveinputposts. php ) ; // Génération d un $id d i f f i c i l e à d e v i n e r. 39 $id = hash ( sha512, $numerorue. $rue. $complementadresse. $codepostal. $ v i l l e. $pays ) ;

206 Chapitre 10 : Bases de Données et PHP Data Objects 41 // Exécution de l a r equête. ( Tous l e s? de l a r e q u ê t e ont é t é l i é s à des v a r i a b l e s ) 42 i f ( $statement >execute ( ) === f a l s e ) { 43 $dataerror [ execute query ] = Problème d e x é c u t i o n de l a r e q u ê t e. 44. ( par exemple, une l i g n e avec c e t t e c l é p r i m a i r e $id e x i s t e déjà... ) ; 45 r e q u i r e ( vueerreur. php ) ; 46 } e l s e { // Code de l a vue : 47 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 48 outputentetehtml5 ( Requêtes Préparées, UTF 8, mystyle. css ) ; 49 echo <h1>requêtes Préparées ( 1 )</h1> ; 50 echo <p>la r equête a é t é exécutée.</p> ; 51 outputfinfichierhtml5 ( ) ; 52 } // Fermeture de l a connexion ( connexion non p e r s i s t a n t e ) 55 $statement = n u l l ; 56 $dbh = n u l l ; 57?> Voici un autre exemple de requête préparée avec une requête de type SELECT. exemples/pdo/ex08_requetesprepareesselect.php 1 <?php 2 // Connexion à l a base de données : 3 require_once ( dirname ( FILE ). / ex03_connecttodatabasepdo. php ) ; 4 5 // Préparation de l a r equête ( chaîne r e p r é s e n t a n t une r e q u ê t e SQL 6 // s a u f que l e s v a l e u r s à i n s é r e r dont des? 7 $statement = $dbh >prepare ( SELECT * FROM Adresse WHERE codepostal =? ) ; 8 9 // Test d e r r e u r en supposant l e mode de g e s t i o n des e r r e u r s PDO : : ERRMODE_SILENT 10 // ( sinon, avec l e mode PDO : :ERRMODE_EXCEPTION i l f a u d r a i t u t i l i s e r avec try... catch ) 11 i f ( $statement === f a l s e ) { 12 $dataerror [ preparation query ] = Problème l o r s de l a p r é p a r a t i o n de l a requête. 13. ( par exemple, l a syntaxe de l a r e q u ê t e e s t i n v a l i d e 14. pour l e d r i v e r u t i l i s é... ) ; 15 r e q u i r e ( vueerreur. php ) ; 16 d i e ( ) ; 17 } // L i a i s o n de l a v a r i a b l e $_GET[ codepostal ] avec l e? de l a r e q u ê t e préparée : 20 // Le premier paramètre de bindparam e s t i c i l e numéro du?, à s a v o i r 1 21 $statement >bindparam ( 1, $_GET[ codepostal ] ) ; // Test d e r r e u r en supposant l e mode de g e s t i o n des e r r e u r s PDO : : ERRMODE_SILENT 24 // ( sinon, avec l e mode PDO : :ERRMODE_EXCEPTION i l f a u d r a i t u t i l i s e r avec try... catch ) 25 i f ( $statement >execute ( )!== f a l s e ) { // Code de l a vue : 26 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 27 outputentetehtml5 ( Requêtes Préparées, UTF 8, mystyle. css ) ; 28 echo <h1>requêtes Préparées ( 2 )</h1> ; 205

207 Rémy Malgouyres, Programmation Web 29 // A f f i c h a g e des r é s u l t a t s de l a r e q u ê t e 30 f o r e a c h ( $statement as $row ) { 31 echo <p> ; 32 echo $row [ numerorue ].,. $row [ rue ]., ; 33 i f (! empty ( $row [ complementadresse ] ) ) 34 echo $row [ complementadresse ]., ; 35 echo $row [ codepostal ]. ; 36 echo $row [ v i l l e ]. ; 37 echo $row [ pays ] ; 38 echo </p> ; 39 } 40 outputfinfichierhtml5 ( ) ; 41 } e l s e { // Erreur l o r s de l e x é c u t i o n de l a r e q u ê t e 42 $dataerror [ execute query ] = Problème d e x é c u t i o n de l a r e q u ê t e. 43. ( par exemple, une l i g n e avec c e t t e c l é p r i m a i r e $id e x i s t e déjà... ) ; 44 r e q u i r e ( vueerreur. php ) ; 45 d i e ( ) ; 46 } // Fermeture de l a connexion ( connexion non p e r s i s t a n t e ) 49 $statement = n u l l ; 50 $dbh = n u l l ; 51?> 10.4 Classe Singleton de Connexion à une Base de Données Nous présentons ici une classe de gestionnaire de connexion à une base de données. La connexion est persistante, c est à dire que l on ne va pas réinitialiser la connexion sans arrêt. Cette gestion de la connexion permet l exécution plus rapide de requêtes, en évitant d établir à chaque fois la connexion. Pour cela, la classe suit me Design Pattern du Singleton. Cela garantit que nous n aurons qu une seule instance de la classe à la fois. La méthode prepareandexecutequery prend deux arguments $requete et $args : 1. la requête avec des? 2. un tableau des arguments qui doivent remplacer les? dans la requête. exemples/pdo/ex12_classedatabasemanager.php 1 <?php 2 3 /** Classe permettant de g é r e r l a connection au s e r v e u r de bases de données 5 L e x é c u t i o n de r e q u ê t e s SQL avec p r é p a r a t i o n o f f e r t e s e r v i c e compris. 6 La c l a s s e e s t g é r é e avec l e pattern SINGLETON, qui permet 7 d a v o i r un exemplaire unique du g e s t i o n a i r e de connection, 8 pour une connexion p e r s i s t a n t e. 9 */ 10 class DataBaseManager{ 206

208 Chapitre 10 : Bases de Données et PHP Data Objects 11 // G e s t i o n n a i r e de connection à l a base de données avec PDO 12 // Variable de c l a s s e. 13 s t a t i c p r i v a t e $dbh = n u l l ; // Référence de l unique i n s t a n c e de l a c l a s s e. 16 // Variable de c l a s s e, i n i t i a l e m e n t n u l l 17 s t a t i c p r i v a t e $ i n s t a n c e=n u l l ; // Données n é c e s s a i r e s à l a connexion par 20 // l e c o n s t r u c t e u r de PDO : 21 s t a t i c p r i v a t e $db_host= mysql :host=l o c a l h o s t ; ; 22 s t a t i c p r i v a t e $db_name= dbname=exampledatabase ; 23 s t a t i c p r i v a t e $db_user= remy ; 24 s t a t i c p r i v a t e $db_password= my_password ; /** 27 Constructeur p r i v é. 28 * Personne ne peut c r é e r des i n s t a n c e s à t i r e l a r i g o t 29 * car dans l e s i n g l e t o n i l ne d o i t y a v o i r qu une s e u l e i n s t a n c e 30 */ 31 p r i v a t e f u n c t i o n construct ( ) { 32 try { 33 // Création de l i n s t a n c e de PDO ( database handler ). 34 s e l f : :$dbh = new PDO( s e l f : :$db_host. s e l f : :$db_name, s e l f : :$db_user, s e l f : : $db_password ) ; 35 // Rendre l e s e r r e u r s PDO d é t e c t a b l e s et g é r a b l e s par e x c e p t i o n s : 36 s e l f : :$dbh >s e t A t t r i b u t e (PDO : :ATTR_ERRMODE, PDO : :ERRMODE_EXCEPTION) ; 37 } catch ( PDOException $e ) { 38 echo <p>erreur de connexion à l a base de données.<br/> 39. Vous n avez pas besoin d en s a v o i r plus </p> ; 41 d i e ( ) ; 42 } 43 } /** 46 Méthode s t a t i q u e p l u b l i q u e d a c c è s à l unique i n s t a n c e. 47 * Si l i n s t a n c e n e x i s t e pas, on l a c r é e. 48 * On retourne e n s u i t e l unique i n s t a n c e. 49 */ 50 p u b l i c s t a t i c f u n c t i o n g e t I n s t a n c e ( ) 51 { 52 i f ( n u l l === s e l f : :$ i n s t a n c e ) { 53 s e l f : :$ i n s t a n c e = new s e l f ; 54 } 55 return s e l f : :$ i n s t a n c e ; 56 } /** 59 Prépare et exécute une r e q u ê t e. 60 s t r i n g $requete : r e q u ê t e avec des? 61 s t r i n g [ ] $args : arguments à l i e r ( binder ) aux? dans l a r e q u ê t e 62 */ 63 p u b l i c f u n c t i o n prepareandexecutequery ( $requete, $args ) { 64 // r é c u p é r a t i o n du nombre d arguments : 65 $numargs = count ( $args ) ; 207

209 Rémy Malgouyres, Programmation Web 66 // Test de r equête préparée v a l a b l e 67 // Une r equête préparée ne d o i t pas c o n t e n i r de g u i l l e m e t s!!! 68 i f ( empty ( $requete )! i s _ s t r i n g ( $requete ) 69 preg_match ( / ( \ \ ) +/, $requete )!== 0) 70 { 71 return f a l s e ; 72 } 73 // Préparation de l a r equête 74 $statement = s e l f : :$dbh >prepare ( $requete ) ; 75 i f ( $statement === f a l s e ) { 76 return f a l s e ; 77 } 78 // On parcours l e s arguments en commençant au deuxième 79 // on commence après l e paramètre $requete 80 f o r ( $ i=1 ; $ i <= $numargs ; $ i++){ 81 // Lien e n t r e l argument et l e? numéro i 82 // ( rappel : l e s? sont numérotés à p a r t i r de 1) 83 $statement >bindparam ( $i, $args [ $i 1]) ; 84 } // Exécution de l a r equête préparée : 87 $statement >execute ( ) ; i f ( $statement === f a l s e ) { 90 return f a l s e ; 91 } try { 94 // T r a n s f e r t des r é s u l t a t s de l a r e q u ê t e dans un array 95 $ r e s u l t s = $statement >f e t c h A l l (PDO : :FETCH_ASSOC) ; 96 } catch ( PDOException $e ) { 97 // La requête a é t é exécutée mais pas de r é s u l t a t s 98 // La requête n e s t pas de type SELECT $ r e s u l t s = true ; 100 } // d e s t r u c t i o n des données du PDOstatement 103 $statement >c l o s e C u r s o r ( ) ; 104 $statement = n u l l ; return $ r e s u l t s ; // r e t o u r des données de r e q u ê t e 107 } /** 110 on i n t e r d i t l e clonage ( pour l e pattern s i n g l e t o n. 111 */ 112 p r i v a t e f u n c t i o n clone ( ) {} 113 } 114?> Voici une utilisation de cette classe de gestion de la base de données, avec une requête qui affiche les adresses dont le code postal est passé par la méthode GET. exemples/pdo/ex13_testsingletonpdo.php 1 <?php 2 require_once ( dirname ( FILE ). / ex12_classedatabasemanager. php ) ; 208

210 Chapitre 10 : Bases de Données et PHP Data Objects 3 4 $statement = DataBaseManager : :g e t I n s t a n c e ( ) >prepareandexecutequery ( 5 SELECT * FROM Adresse WHERE codepostal =?, 6 array ($_GET[ codepostal ] ) ) ; 7 8 require_once ( dirname ( FILE ). / commonfunctions. php ) ; 9 outputentetehtml5 ( Test de Fonction de Préparation de Requête, 10 UTF 8, mystyle. css ) ; 11 i f ( $statement!== f a l s e ) { 12 // A f f i c h a g e des r é s u l t a t s de l a r e q u ê t e 13 f o r e a c h ( $statement as $row ) { 14 echo <p> ; 15 echo $row [ numerorue ].,. $row [ rue ]., ; 16 i f (! empty ( $row [ complementaddr ] ) ) 17 echo $row [ complementaddr ]., ; 18 echo $row [ codepostal ]. ; 19 echo $row [ v i l l e ]. ; 20 echo $row [ pays ] ; 21 echo </p> ; 22 } 23 } e l s e { // Erreur l o r s de l e x é c u t i o n de l a r e q u ê t e 24 $dataerror [ ] = Problème l o r s de l a p r é p a r a t i o n de l a r e q u ê t e. 25. ( par exemple, l a donnée codepostal passée par GET e s t i n v a l i s e... ) ; 26 r e q u i r e ( vueerreur. php ) ; 27 d i e ( ) ; 28 } 29 outputfinfichierhtml5 ( ) ; 30?> 209

211 Cinquième partie Conception d Architectures Avancées 210

212 Table of Contents 11 Analyse Fonctionnelle Storyboards Diagrammes de Cas d Utilisations Organisation des Répertoires et Configuration Organisation des Répertoires Autoload La classe Config : éviter les URL en dûr Architectures MVC et DAL Le Contrôleur Le Modèle Les Vues La Gateway pour les instances d Adresse Utilisateurs et Front Controller Storyboards Diagramme de Cas d Utilisation Le Front-Controller Gestion de l Authentification Utilitaires d Authentification Modèle et Gateway de la table User Gestion des sessions et des cookies

213 212 TABLE OF CONTENTS

214 Chapitre 11 Analyse Fonctionnelle 11.1 Storyboards a Storyboards (b) La vue affichant toutes les adresses (a) Vues normale d une instance Figure 11.1 : Storyboards : Vues d affichage d instances et de collection d instances d Adresse 213

215 Rémy Malgouyres, Programmation Web (a) La vue de saisie d une instance (b) La vue d erreur de saisie Figure 11.2 : Storyboards : Vue normale et vue d erreur de saisie d une instance d Adresse 11.2 Diagrammes de Cas d Utilisations Dans les storyboards précédents, tous les liens et les boutons correspondent à des actions (événements utilisateur) que nous résumons dans un diagramme de cas d utilisation. Figure 11.3 : Use Case Diagram : Les actions possibles pour l utilisateur 214

216 Chapitre 12 Organisation des Répertoires et Configuration 12.1 Organisation des Répertoires Nous allons adopter une organisation des répertoire très précise (voir arborescence ci-contre) pour permettre à la classe Autoload, décrite dans la partie 12.2, de charger automatiquement les classes. La liste des sous-répertoire contenant des classes (ici config, controlleur, metier, etc.) sera fournie à l autoload pour lui permettre de trouver les fichiers sources des classes. Les classes du répertoire metier on été étudiées dans la chapitre 7. Les classes du répertoire vue/classes ont été étudiées dans ce même chapitre 7. et dans le chapitre 4. La classe DataBaseManager du répertoire persistance a été étudiée dans la partie La classe AdresseGateway qui gère, via la classe DataBaseManager, la génération et l exécution des requêtes SQL concernant la table Adresse, sera étudiée dans la partie Les classes des répertoires controleur et modele, ainsi que les vues à la racine du répertoire vue, qui constitue le coeur de l architecture dite Modèle, Vue, Contrôleur (MVC), seront étudiées au chapitre index.php --config -- Autoload.php -- Config.php -- controleur -- Controleur.php -- validationadresse.php -- css -- defaultstyle.css -- metier -- AdresseFabrique.php -- Adresse.php -- AdressePropertiesTrait.php -- ExpressionsRegexUtils.php -- modeles -- ModelAdresse.php -- ModelCollectionAdresse.php -- Model.php -- persistance -- AdresseGateway.php -- DataBaseManager.php -- vue -- classes -- AdresseFormView.php -- AdresseView.php -- FormManager.php -- VueHtmlUtils.php -- vueaccueil.php -- vueafficheadresse.php -- vuecollectionadresse.php -- vueeditionadresse.php -- vueerreurdefault.php -- vuesaisieadresseerror.php -- vuesaisieadresse.php 215

217 Rémy Malgouyres, Programmation Web 12.2 Autoload La classe Autoload déclare et implémente une méthode callback qui sera appelée lors de l utilisation dans le programme d une classe inconnue. La méthode callback cherche alors dans les répertoires un fichier source PHP dont le nom correspond à celui de la classe en question, et charge ce fichier source pour définir la classe à la vollée. exemples/mvclatex/expoly/ex01_autoload.php 1 <?php 2 /** 3 c l a s s e Autoload : permet de charger automatiquement l e s c l a s s e s. 4 * La méthode autoloadcallback ( ) permer de charger l e code source 5 * d une c l a s s e dont l e nom e s t passé en paramètre. 6 * Pour cela, l a méthode load ( ) d é c l a r e autoloadcallback ( ) 7 * par un appel à s p l _ a u t o l o a d _ r e g i s t e r ( ) 8 */ 9 class Autoload 10 { 11 // r é f é r e n c e v e r s l unique i n s t a n c e d Autoload 12 p r i v a t e s t a t i c $m_instance = n u l l ; /** 15 Chargement de l unique i n s t a n c e et d é c l a r a t i o n du c a l l b a c k d autoload. 16 */ 17 p u b l i c s t a t i c f u n c t i o n load ( ) 18 { 19 i f ( n u l l!== s e l f : :$m_instance ) { // Test : s i l i n s t a n c e e x i s t e. 20 throw new Exception ( Erreur l autoload ne peut ê t r e chargée qu une f o i s :. CLASS ) ; 21 } 22 // A l l o c a t i o n de l i n s t a n c e ( c o n s t r u c t e u r par défaut ) : 23 s e l f : :$m_instance = new s e l f ( ) ; 24 // D é c l a r a t i o n du c a l l b a c k chargé d i n c l u r e l e s c l a s s e s : 25 i f (! s p l _ a u t o l o a d _ r e g i s t e r ( array ( s e l f : :$m_instance, autoloadcallback ), f a l s e ) ) { 26 throw new Exception ( I m p o s s i b l e de l a n c e r l autoload :. CLASS ) ; 27 } 28 } /** 31 D é s a c t i v a t i o n du c a l l b a c k d autoload et d e s t r u c t i o n de l i n s t a n c e. 32 */ 33 p u b l i c s t a t i c f u n c t i o n shutdown ( ) 34 { 35 i f ( n u l l!== s e l f : :$m_instance ) { 36 i f (! spl_autoload_unregister ( array ( s e l f : :$m_instance, _autoload ) ) ) { 37 throw new Exception ( I m p o s s i b l e d a r r ê t e r l autoload :. CLASS ) ; 38 } 39 s e l f : :$m_instance = n u l l ; 40 } 41 } /** 216

218 Chapitre 12 : Organisation des Répertoires et Configuration 44 Callback d Autoload. 45 * Cette méthode e s t appelée automatiquement en cas d i n s t a n c i a t i o n 46 * d une c l a s s e inconnue. La méthode charge a l o r s l a c l a s s e en q u e s t i o n. 47 * 48 class : nom de l a c l a s s e à charger. 49 * 50 L a r b o r e s c e n c e des r é p e r t o i r e s et l e s noms de f i c h i e r s PHP 51 * contenant l e s c l a s s e s sont imposés pour permettre àà c e t t e f o n c t i o n 52 * de trouver l e nom du f i c h i e r PHP à p a r t i r du nom de l a c l a s s e. 53 */ 54 p r i v a t e s t a t i c f u n c t i o n autoloadcallback ( $ c l a s s ) 55 { 56 // Racine du s i t e 57 g l o b a l $ r o o t D i r e c t o r y ; 58 // Nom du f i c h i e r PHP contenant l a c l a s s e : 59 $sourcefilename = $ c l a s s.. php ; 60 // L i s t e des sous r é p e r t o i r e s contenant des d é f i n i t i o n s de c l a s s e s 61 $ d i r e c t o r y L i s t =array (, c o n f i g /, modeles /, 62 c o n t r o l e u r /, metier /, p e r s i s t a n c e /, 63 vue/ c l a s s e s / ) ; 64 // Parcours de tous l e s sous r é p e r t o i r e s 65 f o r e a c h ( $ d i r e c t o r y L i s t as $subdir ) { 66 // Chemin v e r s l e f i c h i e r 67 $ f i l e P a t h=$ r o o t D i r e c t o r y. $subdir. $sourcefilename ; 68 // s i l e f i c h i e r e x i s t e 69 i f ( f i l e _ e x i s t s ( $ f i l e P a t h ) ) 70 { 71 // Chargement de l a c l a s s e : 72 i n c l u d e ( $ f i l e P a t h ) ; 73 } 74 } } 77 } ?> 12.3 La classe Config : éviter les URL en dûr La classe Config permet de compléter les informations sur l arborescence des répertoires, en indiquant les chemins vers les vues, les vues d erreurs, ou des ressources comme des feuilles de style CSS, à partir de la racine du site. Ceci permet ensuite, dans le code, d éviter les URL en dur en obtenant le chemin dans un tableau. Ainsi, si on change l emplacement des fichiers de ressources ou de vues par la suite, il n y a alors pas besoin de chercher toutes les occurrences de liens cassés dans tous les fichiers sources, il suffit de changer la classe Config. Cela facilite fortement la maintenance du site. exemples/mvclatex/expoly/ex02_config.php 1 <?php 2 /** 3 Classe de c o n f i g u r a t i o n 4 * Donne a c c è s aux paramères s p é c i f i q u e s concernant l a p p l i c a t i o n 217

219 Rémy Malgouyres, Programmation Web 5 * t e l l e s que l e s chemins v e r s l e s vues, l e s vues d erreur, 6 * l e s hash pour l e s ID de s e s s i o n s, e t c. 7 */ 8 class Config 9 { 10 /** 11 r etourne l e tableau des ( chemins v e r s ) l e s vues 12 */ 13 p u b l i c s t a t i c f u n c t i o n getvues ( ) { 14 // Racine du s i t e 15 g l o b a l $ r o o t D i r e c t o r y ; 16 // R é p e r t o i r e contenant l e s vues 17 $vuedirectory = $ r o o t D i r e c t o r y. vue/ ; 18 return array ( d e f a u l t => $vuedirectory. vueaccueil. php, 19 s a i s i e A d r e s s e => $vuedirectory. v u e S a i s i e A d r e s s e. php, 20 e d i t i o n A d r e s s e => $vuedirectory. vueeditionadresse. php, 21 a f f i c h e A d r e s s e => $vuedirectory. vueafficheadresse. php, 22 a f f i c h e C o l l e c t i o n A d r e s s e => $vuedirectory. v u e C o l l e c t i o n A d r e s s e. php ) ; 23 } /** 26 r etourne l e tableau des ( chemins v e r s ) l e s vues d e r r e u r 27 */ 28 p u b l i c s t a t i c f u n c t i o n getvueserreur ( ) { 29 // Racine du s i t e 30 g l o b a l $ r o o t D i r e c t o r y ; 31 // R é p e r t o i r e contenant l e s vues 32 $vuedirectory = $ r o o t D i r e c t o r y. vue/ ; 33 return array ( d e f a u l t => $vuedirectory. vueerreurdefault. php, 34 s a i s i e A d r e s s e => $vuedirectory. v u e S a i s i e A d r e s s e E r r o r. php ) ; 35 } /** 38 r etourne l e tableau des ( chemins v e r s ) l e s f e u i l l e s de s t y l e CSS 39 */ 40 p u b l i c s t a t i c f u n c t i o n getstylesheetsurl ( ) { // R é p e r t o i r e contenant l e s s t y l e s c s s 43 $cssdirectoryurl = http ://.$_SERVER[ HTTP_HOST ]. / exemples /mvc/ c s s / ; 44 return array ( d e f a u l t => $cssdirectoryurl. d e f a u l t S t y l e. c s s ) ; 45 } /** 48 Génère 10 c h i f f r e s hexa a l é a t o i r e s ( s o i t 5 o c t e t s ) : 49 */ 50 p u b l i c s t a t i c f u n c t i o n generaterandomid ( ) 51 { 52 // Génération de 5 o c t e t s ( pseudo ) a l é a t o i r e s codés en hexa 53 $cryptostrong = f a l s e ; // Variable pour passage par r é f é r e n c e 54 $ o c t e t s = openssl_random_pseudo_bytes ( 5, $cryptostrong ) ; 55 return bin2hex ( $ o c t e t s ) ; 56 } /** 218

220 Chapitre 12 : Organisation des Répertoires et Configuration 59 génère un ID de s e s s i o n pour c o n t r ô l e par a d r e s s e IP 60 * 10 c h i f f r e s hexa a l é a t o i r e s + hash de l a d r e s s e IP. 61 */ 62 p u b l i c s t a t i c f u n c t i o n g e n e r a t e S e s s i o n I d ( ) 63 { 64 return generaterandomid ( ). hash ( md5, $_SERVER[ REMOTE_ADDR ] ) ; 65 } 66 } 67?> 219

221 Chapitre 13 Architectures MVC et DAL 13.1 Le Contrôleur Le contrôleur est chargé de : 1. Reconnaître l action (événement) à réaliser pour l exécuter. 2. Demander la construction du modèle. 3. Tester les erreurs et récupérer les éventuelles exceptions pour éviter un éventuel caca. 4. Appeler la vue (ou la vue d erreur) pour afficher le résultat de l action. L index initialise la donnée deu répertoire racine, charge le code source de l Autoload, puis exécute la méthode load qui déclare le callback chargé d inclure le code source des classes utilisées dans le programme. L index crée ensuite une instance du contrôleur. C est le constructeur du contrôleur qui fait le reste du travail. exemples/mvclatex/expoly/ex03_index.php 1 <?php 2 $ r o o t D i r e c t o r y = dirname ( FILE ). / ; 3 4 // chargement de l a c l a s s e Autoload pour autochargement des c l a s s e s 5 require_once ( $ r o o t D i r e c t o r y. / c o n f i g / Autoload. php ) ; 6 7 try { 8 Autoload : :load ( ) ; 9 } catch ( Exception $e ) { 10 r e q u i r e ( Config : :getvues ( ) [ d e f a u l t ] ) ; 11 } // Création de l i n s t a n c e du c o n t r ô l e u r ( v o i r Controleur. php ) 14 $cont = new Controleur ( ) ; 15?> Le constructeur du contrôleur récupère dans le tableau $_REQUEST (réunion de $_GET, de $_POST et de $_COOKIE), l action à réaliser. Ces actions sont déterminées lors de l analyse dans le diagramme de cas d utilisation (voir la partie 11.2). On fait un switch pour distinguer tous les cas correspondant aux actions, sans oublier le cas default, qui renverra généralement vers la page d accueil, ou encore une vue d erreur par défaut, en cas d action non définie. 220

222 Chapitre 13 : Architectures MVC et DAL exemples/mvclatex/expoly/ex04_controleur.php 1 <?php 2 /** 3 La c l a s s e Controleur i d e n t i f i e l action et a p p e l l e l a mthode 4 * pour c o n s t r u i r e l e modle correspondant l action. 5 * Le c o n t r o l e u r a p p e l l e a u s s i l a vue correspondante. 6 * I l gre a u s s i l e s e x c e p t i o n s et a p p e l l e l e cas chant une vue d e r r e u r. 7 */ 8 class Controleur { 9 10 /** 11 C e s t dans l e c o n t r u c t e u r que l e c o n t r l e u r f a i t son t r a v a i l. 12 */ 13 f u n c t i o n construct ( ) { 14 try 15 { 16 // Rcupration de l action 17 $ a c t i o n=$_request[ action ] ; // On d i s t i n g u e des cas d u t i l i s a t i o n, s u i v a n t l action 20 switch ( $ a c t i o n ) { 21 case get : // A f f i c h a g e d une Adresse p a r t i r de son ID 22 $id = f i l t e r _ v a r ($_REQUEST[ id ], FILTER_SANITIZE_STRING) ; 23 $modele = ModelAdresse : :getmodeladresse ( $ i d ) ; 24 i f ( $modele >geterror ( ) === f a l s e ) { 25 r e q u i r e ( Config : :getvues ( ) [ a f f i c h e A d r e s s e ] ) ; 26 } e l s e { 27 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 28 } 29 break ; 30 case get a l l : // A f f i c h a g e de t o u t e s l e s Adresse s 31 $modele = ModelCollectionAdresse : :getmodeladresseall ( ) ; 32 i f ( $modele >geterror ( ) === f a l s e ) { 33 r e q u i r e ( Config : :getvues ( ) [ a f f i c h e C o l l e c t i o n A d r e s s e ] ) ; 34 } e l s e { 35 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 36 } 37 break ; 38 case s a i s i e : // S a i s i e d une n o u v e l l e Adresse 39 $modele = ModelAdresse : :getmodeldefaultadresse ( ) ; 40 r e q u i r e ( Config : :getvues ( ) [ s a i s i e A d r e s s e ] ) ; 41 break ; 42 case e d i t : // S a i s i e des m o d i f i c a t i o n s d une Adresse 43 $id = f i l t e r _ v a r ($_REQUEST[ id ], FILTER_SANITIZE_STRING) ; 44 $modele = ModelAdresse : :getmodeladresse ( $ i d ) ; 45 i f ( $modele >geterror ( ) === f a l s e ) { 46 r e q u i r e ( Config : :getvues ( ) [ e d i t i o n A d r e s s e ] ) ; 47 } e l s e { 48 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 49 } 50 break ; 51 case post : // Met j o u r une Adresse dans l a BD 52 r e q u i r e ( dirname ( FILE ). / v a l i d a t i o n A d r e s s e. php ) ; 53 $modele = ModelAdresse : :getmodeladressepost ( $id, $numerorue, $rue, 54 $complementadresse, $codepostal, $ v i l l e, $pays ) ; 55 i f ( $modele >geterror ( ) === f a l s e ) { 221

223 Rémy Malgouyres, Programmation Web 56 r e q u i r e ( Config : :getvues ( ) [ a f f i c h e A d r e s s e ] ) ; 57 } e l s e { 58 i f (! empty ( $modele >geterror ( ) [ p e r s i s t a n c e ] ) ) { 59 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 60 } e l s e { 61 r e q u i r e ( Config : :getvueserreur ( ) [ s a i s i e A d r e s s e ] ) ; 62 } 63 } 64 break ; 65 case put : // Cration d une n o u v e l l e Adresse dans l a BD 66 r e q u i r e ( dirname ( FILE ). / v a l i d a t i o n A d r e s s e. php ) ; 67 $modele = ModelAdresse : :getmodeladresseput ( $numerorue, $rue, 68 $complementadresse, $codepostal, $ v i l l e, $pays ) ; 69 i f ( $modele >geterror ( ) === f a l s e ) { 70 r e q u i r e ( Config : :getvues ( ) [ a f f i c h e A d r e s s e ] ) ; 71 } e l s e { 72 i f (! empty ( $modele >geterror ( ) [ p e r s i s t a n c e ] ) ) { 73 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 74 } e l s e { 75 r e q u i r e ( Config : :getvueserreur ( ) [ s a i s i e A d r e s s e ] ) ; 76 } 77 } 78 break ; 79 case d e l e t e : // Supression d une Adresse p a r t i r de son ID 80 $id = f i l t e r _ v a r ($_REQUEST[ id ], FILTER_SANITIZE_STRING) ; 81 $modele = ModelAdresse : :d e l e t e A d r e s s e ( $id ) ; 82 i f ( $modele >geterror ( ) === f a l s e ) { 83 r e q u i r e ( Config : :getvues ( ) [ a f f i c h e A d r e s s e ] ) ; 84 } e l s e { 85 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 86 } 87 break ; 88 d e f a u l t : // L a c t i o n i n d f i n i e ( page par dfaut, i c i a c c u e i l ) 89 r e q u i r e ( Config : :getvues ( ) [ d e f a u l t ] ) ; 90 break ; 91 } 92 } 93 catch ( Exception $e ) // Page d e r r e u r par dfaut 94 { 95 $modele = new Model ( array ( exception => $e >getmessage ( ) ) ) ; 96 r e q u i r e ( Config : :getvueserreur ( ) [ d e f a u l t ] ) ; 97 } 98 } 99 } 100?> Comme expliqué au chapitre 7, si les données issues du tableau $_REQUEST sont utilisées, elles doivent être systématiquement filtrées. Un appel de méthode construit un modèle, instance de classe qui contiendra les données nécessaires à la vue, et un tableau d erreur, éventuellement non vide. La construction du modèle est décrite dans la partie 13.2 ci-dessous. Le contrôleur appelle ensuite la vue, qui sera éventuellement une vue d erreur en cas de tableau d erreurs non vide. 222

224 Chapitre 13 : Architectures MVC et DAL 13.2 Le Modèle Une classe de base appelée Model, générique, contient le tableau des erreurs et son accesseur (qui renvoit le booléen false en cas de tableau vide). Dans notre implémentation, le modèle contient aussi du texte (ici le titre) à afficher dans la vue. exemples/mvclatex/expoly/ex05_model.php 1 <?php 2 class Model{ 3 /** 4 D i c t i o n n a i r e d e r r e u r s ( c o u p l e s type => mmessage ) 5 */ 6 p r o t e c t e d $dataerror ; 7 8 /** 9 return f a l s e en l absence d e r r e u r s, l a c o l l e c t i o n d e r r e u r s sinon 10 */ 11 p u b l i c f u n c t i o n geterror ( ) { 12 i f ( empty ( $ t h i s >dataerror ) ) { 13 return f a l s e ; 14 } 15 return $ t h i s >dataerror ; 16 } p u b l i c f u n c t i o n construct ( $dataerror ) { 19 $ t h i s >dataerror = $dataerror ; 20 } 21 } 22?> La classe ModelAdresse, qui hérite de Model contient les données d une instance d Adresse, avec son accesseur getdata(). Les méthodes de la classe ModelAdresse correspondent aux différentes actions qui ne portent que sur une seule adresse (suppression d une adresse, saisie ou modification d une adresse, affichage des détails d une adresse, etc.) Ces méthodes appelle des méthodes d accès aux données de la classe AdresseGateway pour implémenter la persistence. exemples/mvclatex/expoly/ex06_modeladresse.php 1 <?php 2 /** 3 Classe Modèle pour s t o c k e r une Adresse 4 * Construit un modèle de données pour l e s vues 5 * a f f i c h a n t une unique a d r e s s e. 6 * Les données peuvent v e n i r d un f o r m u l a i r e ou d un a c c è s à l a BD. 7 */ 8 class ModelAdresse extends Model 9 { 10 /** 11 I n s t a n c e d adresse, données métier du modèle 12 */ 13 p r i v a t e $ a d r e s s e ; /** 16 T i t r e p r i n c i p a l de l a vue 17 */ 18 p r i v a t e $ t i t l e ; 223

225 Rémy Malgouyres, Programmation Web /** 21 * Donne a c c è s à l a c o l l e c t i o n d a d r e s s e s 22 */ 23 p u b l i c f u n c t i o n getdata ( ) 24 { 25 return $ t h i s >a d r e s s e ; 26 } /** 29 * Donne a c c è s à l a c o l l e c t i o n d a d r e s s e s 30 */ 31 p u b l i c f u n c t i o n g e t T i t l e ( ) 32 { 33 return $ t h i s >t i t l e ; 34 } /** 37 Retourne un modèle avec une a d r e s s e à p a r t i r de son ID 38 * par a c c è s à l a base de données. 39 */ 40 p u b l i c s t a t i c f u n c t i o n getmodeldefaultadresse ( ) { 41 $model = new s e l f ( array ( ) ) ; 42 // Appel de l a couche d a c c è s aux données : 43 $model >a d r e s s e = Adresse : :g e t d e f a u l t A d r e s s e ( ) ; 44 $model >t i t l e = S a i s i e d une a d r e s s e ; 45 return $model ; 46 } /** 49 Retourne un modèle avec une a d r e s s e à p a r t i r de son ID 50 * par a c c è s à l a base de données. 51 */ 52 p u b l i c s t a t i c f u n c t i o n getmodeladresse ( $id ) { 53 $model = new s e l f ( array ( ) ) ; 54 // Appel de l a couche d a c c è s aux données : 55 $model >a d r e s s e = AdresseGateway : :getadressebyid ( $model >dataerror, $id ) ; 56 $model >t i t l e = A f f i c h a g e d une a d r e s s e ; 57 return $model ; 58 } 59 /** 60 I n s è r e une a d r e s s e en c r é a n t un nouvel ID 61 * par a c c è s à l a base de données. 62 */ 63 p u b l i c s t a t i c f u n c t i o n getmodeladressepost ( $id, $numerorue, $rue, 64 $complementaddr, 65 $codepostal, $ v i l l e, $pays ) { 66 $model = new s e l f ( array ( ) ) ; // Appel de l a couche d a c c è s aux données : 69 $model >a d r e s s e = AdresseGateway : :postadresse ( $model >dataerror, $id, 70 $numerorue, $rue, $complementaddr, 71 $codepostal, $ v i l l e, $pays ) ; 72 $model >t i t l e = L a d r e s s e a é t é mise à j o u r ; 73 return $model ; 74 } 224

226 Chapitre 13 : Architectures MVC et DAL /** 77 I n s è r e une a d r e s s e en c r é a n t un nouvel ID 78 * par a c c è s à l a base de données. 79 */ 80 p u b l i c s t a t i c f u n c t i o n getmodeladresseput ( $numerorue, $rue, $complementaddr, 81 $codepostal, $ v i l l e, $pays ) { 82 $model = new s e l f ( array ( ) ) ; // Appel de l a couche d a c c è s aux données : 85 $model >a d r e s s e = AdresseGateway : :putadresse ( $model >dataerror, 86 $numerorue, $rue, $complementaddr, 87 $codepostal, $ v i l l e, $pays ) ; 88 $model >t i t l e = L a d r e s s e a é t é i n s é r é e ; 89 return $model ; 90 } /** 93 Retourne un modèle avec une a d r e s s e à p a r t i r de son ID 94 * par a c c è s à l a base de données. 95 */ 96 p u b l i c s t a t i c f u n c t i o n d e l e t e A d r e s s e ( $id ) { 97 $model = new s e l f ( array ( ) ) ; 98 // Appel de l a couche d a c c è s aux données : 99 $model >a d r e s s e = AdresseGateway : :d e l e t e A d r e s s e ( $model >dataerror, $id ) ; 100 $model >t i t l e = Adresse supprimée ; 101 return $model ; 102 } 103 } 104?> La classe ModelCollectionAdresse, qui hérite de Model contient les données d une collection d instances d Adresse, avec son accesseur getdata(), qui cette fois renvoie une collection. Les méthodes de la classe ModelCollectionAdresse correspondent aux différentes actions qui ne portent que sur une collection d adresse (ici uniquement : afficher toute la table). Ces méthodes appelle des méthodes d accès aux données de la classe AdresseGateway pour implémenter la persistence. exemples/mvclatex/expoly/ex07_modelcollectionadresse.php 1 <?php 2 Classe Modle pour s t o c k e r une c o l l e c t i o n de Adresses 3 * 4 */ 5 class ModelCollectionAdresse extends Model 6 { 7 /** 8 C o l l e c t i o n d a d r e s s e s, donnes mtier du modle 9 */ 10 p r i v a t e $ c o l l e c t i o n A d r e s s e ; /** 13 * Donne accs l a c o l l e c t i o n d a d r e s s e s 14 */ 15 p u b l i c f u n c t i o n getdata ( ) 16 { 225

227 Rémy Malgouyres, Programmation Web 17 return $ t h i s >c o l l e c t i o n A d r e s s e ; 18 } /** 21 Constructeur par dfaut (priv, c r e des c o l l e c t i o n s v i d e s ) 22 */ 23 p r i v a t e f u n c t i o n contruct ( ) 24 { 25 $ t h i s >c o l l e c t i o n A d r e s s e = array ( ) ; 26 $ t h i s >dataerror = array ( ) ; 27 } /** 30 Retourne un modle avec l a c o l l e c t i o n de t o u t e s l e s a d r e s s e s 31 * par accs l a base de donnes. 32 */ 33 p u b l i c s t a t i c f u n c t i o n getmodeladresseall ( ) { 34 $model = new s e l f ( array ( ) ) ; 35 // Appel de l a couche d accs aux donnes : 36 $model >c o l l e c t i o n A d r e s s e = AdresseGateway : :g e t A d r e s s e A l l ( $model >dataerror ) ; 37 return $model ; 38 } 39 } 40?> Notons qu il ne s agit pas vraiment ici de polymorphisme. L héritage de la classe de base Model, qui correspond bien à une relation de spécialisation, n a pas la propriété de substitution, car les données dans les classes spécialisées (instance dans un cas et collection dans l autre, ne se correspondent pas. L héritage est ici utilisé pour factoriser uniquement. Ce type de relation pourrait aussi (devraient plutôt?) être implémenté par une composition. On pourrait aussi implémenter l instance d adresse comme une collection avec un seul élément pour n avoir qu une seule classe Les Vues Les vues ne font aucun test et se contentent d afficher le modèle qui, en l absence de bug, doit s afficher correctement. exemples/mvclatex/expoly/ex08_vueafficheadresse.php 1 <?=VueHtmlUtils : :entetehtml5 ( Bienvenue sur notre s i t e, UTF 8, 2 Config : :getstylesheetsurl ( ) [ d e f a u l t ] )?> 3 <h1><?=$modele >g e t T i t l e ( )?></h1> 4 <?=AdresseView : :gethtmldevelopped ( $modele >getdata ( ) )?> 5 6 <a href=? >Revenir à l a c c u e i l</a> 7 <?=VueHtmlUtils : :f i n F i c h i e r H t m l 5 ( ) ;?> exemples/mvclatex/expoly/ex09_vuecollectionadresse.php 1 <?=VueHtmlUtils : :entetehtml5 ( Bienvenue sur notre s i t e, UTF 8, 226

228 Chapitre 13 : Architectures MVC et DAL 2 Config : :getstylesheetsurl ( ) [ d e f a u l t ] )?> 3 <h1>toutes l e s a d r e s s e s</h1> 4 <a href=? >Revenir à l a c c u e i l</a> 5 <?php 6 echo <table ><tbody> ; 7 f o r e a c h ( $modele >getdata ( ) as $ a d r e s s e ) { 8 echo <tr> ; 9 echo <td><a h r e f=\?a c t i o n=d e l e t e&id=. $adresse >g e t I d ( ). \ >supprimer </a ></td> ; 10 echo <td><a h r e f=\?a c t i o n=e d i t&id=. $adresse >g e t I d ( ). \ >modifier </a></td > ; 11 echo <td>. AdresseView : :gethtmlcompact ( $ a d r e s s e ). </td> ; 12 echo <tr> ; 13 } 14 echo </tbody></table > ; 15?> 16 <?=VueHtmlUtils : :f i n F i c h i e r H t m l 5 ( ) ;?> exemples/mvclatex/expoly/ex10_vuesaisieadresseerror.php 1 <?=VueHtmlUtils : :entetehtml5 ( Bienvenue sur notre s i t e, UTF 8, 2 Config : :getstylesheetsurl ( ) [ d e f a u l t ] )?> 3 <h1>erreur de s a i s i e d une a d r e s s e</h1> 4 <?=AdresseFormView : :getformerrorshtml (?a c t i o n=. $action, $modele >getdata ( ), $modele >geterror ( ) )?> 5 <a href=? >Revenir à l a c c u e i l</a> 6 <?=VueHtmlUtils : :f i n F i c h i e r H t m l 5 ( ) ;?> 13.4 La Gateway pour les instances d Adresse La Gateway pour les instances d Adresse est une fabrique concrète qui permet de construire les instances d objets métiers (ici de type Adresse) obtenues par des requêtes (ici des requêtes préparées exécutées sur la classe de connection DataBaseManager sur la base de données SQL basée sur PDO). Les méthodes de la classe AdresseGateway construisent les requêtes SQL nécessaires pour implémenter l action, demande leur exécution par la classe de connection, puis appellent la fabrique d adresse (partie 7.3). exemples/mvclatex/expoly/ex11_adressegateway.php 1 <?php 2 class AdresseGateway { 3 /** 4 * Permet de r é c u p é r e r une a d r e s s e à p a r t i r de son ID. 5 dataerror : données d e r r e u r s ( couple type => message ) par r é f é r e n c e 6 id : c l é p rimaire de l a d r e s s e à r é c u p é r e r 7 i n s t a n c e d Adresse en cas de succès, undefined sinon. 8 */ 9 p u b l i c s t a t i c f u n c t i o n getadressebyid(&$dataerror, $id ) { 10 i f ( i s s e t ( $id ) ) { // Exécution de l a requête via l a c l a s s e de connexion ( s i n g l e t o n ) 13 // On r écupère l e s e x c e p t i o n PDO pour é v i t e r l e u r propagation 227

229 Rémy Malgouyres, Programmation Web 14 // On p e r s o n n a l i s e l a g e s t i o n de l e r r e u r 15 try { 16 $queryresults = DataBaseManager : :g e t I n s t a n c e ( ) >prepareandexecutequery ( 17 SELECT * FROM Adresse WHERE id =?, array ( $id ) ) ; 18 } Catch ( Exception $e ) { 19 $dataerror [ requete ] = I m p o s s i b l e d accéder aux données. ; 20 } // Si l e x é c u s s i o n de l a r e q u ê t e a f o n c t i o n n é e 23 i f ( is_array ( $queryresults ) && count ( $queryresults ) == 1) { 24 $row = $queryresults [ 0 ] ; 25 $ a d r e s s e = AdresseFabrique : :getadresse ( 26 $dataerror, 27 $row [ id ], $row [ numerorue ], $row [ rue ], 28 $row [ complementadresse ], $row [ codepostal ], 29 $row [ v i l l e ], $row [ pays ] ) ; 30 } e l s e { 31 $dataerror [ p e r s i s t a n c e ] = Adresse i n t r o u v a b l e. ; 32 } 33 } e l s e { 34 $dataerror [ p e r s i s t a n c e ] = I m p o s s i b l e d accéder aux données. ; 35 } 36 return $ a d r e s s e ; 37 } /** 40 * Permet de r é c u p é r e r une c o l l e c t i o n d a d r e s s e s p r é s e n t e s dans l a t a b l e. 41 dataerror : données d e r r e u r s ( couple type => message ) par r é f é r e n c e 42 c o l l e c t i o n d Adresses en cas de succès, c o l l e c t i o n vide sinon. 43 */ 44 p u b l i c s t a t i c f u n c t i o n g e t A d r e s s e A l l (&$dataerror ) { // Exécution de l a requête via l a c l a s s e de connexion ( s i n g l e t o n ) 47 // On récupère l e s e x c e p t i o n PDO pour é v i t e r l e u r propagation 48 // On p e r s o n n a l i s e l a g e s t i o n de l e r r e u r 49 try { 50 $queryresults = DataBaseManager : :g e t I n s t a n c e ( ) >prepareandexecutequery ( 51 SELECT * FROM Adresse, array ( ) 52 ) ; 53 } Catch ( Exception $e ) { 54 $dataerror [ p e r s i s t a n c e ] = I m p o s s i b l e d accéder aux données. ; 55 } $ c o l l e c t i o n A d r e s s e = array ( ) ; // Si l e x é c u s s i o n de l a r equête a f o n c t i o n n é e 60 i f ( $queryresults!== f a l s e ) { 61 // Parcours des l i g n e s du r é s u l t a t de l a r e q u ê t e : 62 f o r e a c h ( $queryresults as $row ) { 63 // Ajour d une a d r e s s e dans l a c o l l e c t i o n : 64 $ a d r e s s e = AdresseFabrique : :getadresse ( 65 $dataerror, 66 $row [ id ], $row [ numerorue ], $row [ rue ], 67 $row [ complementadresse ], $row [ codepostal ], 68 $row [ v i l l e ], $row [ pays ] ) ; 228

230 Chapitre 13 : Architectures MVC et DAL 69 $ c o l l e c t i o n A d r e s s e [ ] = $ a d r e s s e ; 70 } 71 } e l s e { 72 $dataerror [ p e r s i s t a n c e ] = Aucune a d r e s s e trouvée. ; 73 } return $ c o l l e c t i o n A d r e s s e ; 76 } /** 79 I n s è r e une n o u v e l l e a d r e s s e ( Create ) 80 l i n s t a n c e d Adresse ( e r r e u r s + données de l a a d r e s s e i n s é r é e ) 81 */ 82 p u b l i c s t a t i c f u n c t i o n postadresse (&$dataerror, $id, $numerorue, 83 $rue, $complementaddr, 84 $codepostal, $ v i l l e, $pays ) { 85 $ a d r e s s e = AdresseFabrique : :getadresse ( $dataerror, $id, 86 $numerorue, $rue, $complementaddr, 87 $codepostal, $ v i l l e, $pays ) ; 88 $queryresults = DataBaseManager : :g e t I n s t a n c e ( ) >prepareandexecutequery ( 89 UPDATE Adresse SET numerorue=?, rue =?, 90. complementadresse=?, codepostal =?, v i l l e =?, pays=? 91. WHERE id =?, 92 array ( $adresse >getnumerorue ( ), 93 $adresse >getrue ( ), 94 $adresse >getcomplementadresse ( ), 95 $adresse >getcodepostal ( ), 96 $adresse >g e t V i l l e ( ), 97 $adresse >getpays ( ), 98 $adresse >g e t I d ( ) 99 ) 100 ) ; 101 i f ( $queryresults === f a l s e ) { 102 $dataerror [ p e r s i s t a n c e ] = Problème d e x é c u t i o n de l a r e q u ê t e. ; 103 } return $ a d r e s s e ; 106 } /** 109 I n s è r e une n o u v e l l e a d r e s s e ( Create ) 110 l i n s t a n c e d Adresse ( e r r e u r s + données de l a a d r e s s e i n s é r é e ) 111 */ 112 p u b l i c s t a t i c f u n c t i o n putadresse(&$dataerror, $numerorue, 113 $rue, $complementaddr, 114 $codepostal, $ v i l l e, $pays ) { 115 $ a d r e s s e = AdresseFabrique : :getadresse ( $dataerror, , 116 $numerorue, $rue, $complementaddr, 117 $codepostal, $ v i l l e, $pays ) ; 118 i f (! empty ( $dataerror ) ) { // Si e r r e u r de s a i s i e, on ne m o d i f i e pas l a BD 119 return $ a d r e s s e ; 120 } $queryresults = f a l s e ; 123 $count = 0 ; 229

231 Rémy Malgouyres, Programmation Web 124 // Boucle en cas de c o l l i s i o n de l ID 125 // Autre p o s s i b i l i t é : u t i l i s e r l e nombre de l i g n e s (COUNT) 126 // ou l e maximum par ordre alpha ou hexa des ID 127 // de l a t a b l e pour c a l c u l e r un ID qui n e s t pas p r é s e n t dans l a t a b l e. 128 while ( $queryresults === f a l s e && $count <= 3) { 129 $adresse >s e t I d ( Config : :generaterandomid ( ) ) ; // I d e n t i f i a n t a l é a t o i r e 130 $count++ ; 131 $queryresults = DataBaseManager : :g e t I n s t a n c e ( ) >prepareandexecutequery ( 132 INSERT INTO Adresse ( id, numerorue, rue, 133. complementadresse, codepostal, v i l l e, pays ) 134. VALUES (?,?,?,?,?,?,?), 135 array ( $adresse >g e t I d ( ), 136 $adresse >getnumerorue ( ), 137 $adresse >getrue ( ), 138 $adresse >getcomplementadresse ( ), 139 $adresse >getcodepostal ( ), 140 $adresse >g e t V i l l e ( ), 141 $adresse >getpays ( ) 142 ) 143 ) ; 144 } 145 // 4 c o l l i s i o n s d a f f i l é e, c e s t t r è s louche i f ( $queryresults === f a l s e ) { 147 $dataerror [ p e r s i s t a n c e ] = Problème d e x é c u t i o n de l a r e q u ê t e. ; 148 } return $ a d r e s s e ; 151 } /** 154 Supprime une a d r e s s e à p a r t i r de son ID. 155 * Retourne l e modèle de données ( e r r e u r s + données de l Adresse supprimée ) 156 */ 157 p u b l i c s t a t i c f u n c t i o n d e l e t e A d r e s s e (&$dataerror, $id ) { 158 // Test s i l a d r e s s e e x i s t e et r é c u p é r a t i o n s données à supprimer 159 $ a d r e s s e = s e l f : :getadressebyid ( $dataerror, $id ) ; i f ( empty ( $dataerror ) ) { 162 $queryresults = DataBaseManager : :g e t I n s t a n c e ( ) >prepareandexecutequery ( 163 DELETE FROM Adresse WHERE id =?, 164 array ( $id ) ) ; 165 i f ( $queryresults === f a l s e ) { 166 $dataerror [ p e r s i s t a n c e ] = Problème d e x é c u t i o n de l a r e q u ê t e. ; 167 } 168 } return $ a d r e s s e ; 171 } 172 } 173?> 230

232 Chapitre 14 Utilisateurs et Front Controller 14.1 Storyboards (a) Vues d accueil (b) La vue d authentification Figure 14.1 : Storyboards : Vues d accueil pour visiteur, pour l administrateur, et vue de login (a) La vue visiteur de toutes les adresses (b) Vue admin de toutes les adresses Figure 14.2 : Storyboards : Vue de toutes les adresses suivant le rôle. 231

HMTL. Exemple de fichier HTML. Structure d un document HTML. Exemple de fichier HTML. Balises HTML. IFT1147 Programmation Serveur Web avec PHP

HMTL. Exemple de fichier HTML. Structure d un document HTML. Exemple de fichier HTML. Balises HTML. IFT1147 Programmation Serveur Web avec PHP IFT1147 Programmation Serveur Web avec PHP Un bref survol du langage HTML HMTL HTML: Hypertext Markup Language HTML est essentiellement un langage de description de structure de document (par exemple titre,

Plus en détail

Les outils de création de sites web

Les outils de création de sites web Tuto 1ère séance - p1 Les outils de création de sites web Sources : Réalisez votre site web avec HTML5 et CSS3 de Mathieu Nebra (Edition Le Livre du Zéro) site fr.openclassrooms.com (anciennement «site

Plus en détail

Présentation du Framework BootstrapTwitter

Présentation du Framework BootstrapTwitter COUARD Kévin HELVIG-LARBRET Blandine Présentation du Framework BootstrapTwitter IUT Nice-Sophia LP-SIL IDSE Octobre 2012 Sommaire I. INTRODUCTION... 3 Définition d'un framework... 3 A propos de BootstrapTwitter...

Plus en détail

HTML, CSS, JS et CGI. Elanore Elessar Dimar

HTML, CSS, JS et CGI. Elanore Elessar Dimar HTML, CSS, JS et CGI Elanore Elessar Dimar Viamen GPAs Formation, 13 avril 2006 Sommaire Qu est-ce que HTML? HTML : HyperText Marckup Language XML : extensible Marckup Language Qu est-ce que HTML? HTML

Plus en détail

HTML. Notions générales

HTML. Notions générales 1 HTML Le langage HTML est le langage de base permettant de construire des pages web, que celles-ci soient destinées à être affichées sur un iphone/android ou non. Dans notre cas, HTML sera associé à CSS

Plus en détail

.. CSS. Damien Nouvel. Damien Nouvel (Inalco) CSS 1 / 15

.. CSS. Damien Nouvel. Damien Nouvel (Inalco) CSS 1 / 15 .. CSS Damien Nouvel Damien Nouvel (Inalco) CSS 1 / 15 Feuilles de styles Plan 1. Feuilles de styles 2. Sélecteurs 3. Attributs Damien Nouvel (Inalco) CSS 2 / 15 Feuilles de styles Déportation des styles

Plus en détail

Formation HTML / CSS. ar dionoea

Formation HTML / CSS. ar dionoea Formation HTML / CSS ar dionoea le HTML Hyper Text Markup Language langage descriptif composé de balises interprété par le navigateur page HTML = simple fichier texte (bloc notes, vim,...) les déclarations

Plus en détail

Bernard Lecomte. Débuter avec HTML

Bernard Lecomte. Débuter avec HTML Bernard Lecomte Débuter avec HTML Débuter avec HTML Ces quelques pages ont pour unique but de vous donner les premiers rudiments de HTML. Quand vous les aurez lues, vous saurez réaliser un site simple.

Plus en détail

CRÉER, ROUTER ET GÉRER UNE NEWSLETTER, UN E-MAILING

CRÉER, ROUTER ET GÉRER UNE NEWSLETTER, UN E-MAILING CRÉER, ROUTER ET GÉRER UNE NEWSLETTER, UN E-MAILING Durée : 3J / 21H Formateur : Consultant expert en PAO et Web-marketing. Groupe de : 4 max Formation au web marketing Objectifs : Mettre en oeuvre des

Plus en détail

E-MAILING & NEWSLETTER NEWSLETTER RESPONSIVE

E-MAILING & NEWSLETTER NEWSLETTER RESPONSIVE E-MAILING & NEWSLETTER NEWSLETTER RESPONSIVE mcbenveniste@gmail.com 09/2013 E-MAILING & NEWSLETTER L e-mailing consiste à envoyer des emails simultanément à un nombre important de destinataires dont le

Plus en détail

Programmation Internet Cours 4

Programmation Internet Cours 4 Programmation Internet Cours 4 Kim Nguy ên http://www.lri.fr/~kn 17 octobre 2011 1 / 23 Plan 1. Système d exploitation 2. Réseau et Internet 3. Web 3.1 Internet et ses services 3.1 Fonctionnement du Web

Plus en détail

LES GRANDES ETAPES DE CREATION D UN WEB DESIGN

LES GRANDES ETAPES DE CREATION D UN WEB DESIGN LES GRANDES ETAPES DE CREATION D UN WEB DESIGN PENSER LA STRUCTURE ET LE THEME DU SITE STRUCTURE ET THEME DU SITE Taille (le site sera-t-il extensible ou fixe?) Organisation Thème Couleurs Illustrations

Plus en détail

INTERNET est un RESEAU D ORDINATEURS RELIES ENTRE EUX A L ECHELLE PLANETAIRE. Internet : interconnexion de réseaux (anglais : net = réseau)

INTERNET est un RESEAU D ORDINATEURS RELIES ENTRE EUX A L ECHELLE PLANETAIRE. Internet : interconnexion de réseaux (anglais : net = réseau) CS WEB Ch 1 Introduction I. INTRODUCTION... 1 A. INTERNET INTERCONNEXION DE RESEAUX... 1 B. LE «WEB» LA TOILE, INTERCONNEXION DE SITES WEB... 2 C. L URL : LOCALISER DES RESSOURCES SUR L INTERNET... 2 D.

Plus en détail

STID 2ème année : TP Web/PHP

STID 2ème année : TP Web/PHP STID 2ème année : TP Web/PHP Plan de travail et aide mémoire jean.arnaud@inria.fr Ce document est composé de cinq parties : Un aide mémoire sur les aspects pratiques de la création de sites Une introduction

Plus en détail

Travaux dirigés n 10

Travaux dirigés n 10 Travaux dirigés n 10 IMAC 1 Responsive Web Design Dans ce TD, vous verrez comment concevoir un design web qui s adaptera au terminal sur lequel il sera visualisé. Avant-propos Avec l avènement des smartphones

Plus en détail

Tutoriel : Feuille de style externe

Tutoriel : Feuille de style externe Tutoriel : Feuille de style externe Vous travaillerez à partir du fichier cerise.htm que vous ouvrirez dans NVU. Commencez par remplacer le contenu de la balise Title par : Comment débuter une recherche?

Plus en détail

Installation d un serveur HTTP (Hypertext Transfer Protocol) sous Débian 6

Installation d un serveur HTTP (Hypertext Transfer Protocol) sous Débian 6 Installation d un serveur HTTP (Hypertext Transfer Protocol) sous Débian 6 1 BERNIER François http://astronomie-astrophotographie.fr Table des matières Installation d un serveur HTTP (Hypertext Transfer

Plus en détail

TIC. Réseau informatique. Historique - 1. Historique - 2. TC - IUT Montpellier Internet et le Web

TIC. Réseau informatique. Historique - 1. Historique - 2. TC - IUT Montpellier Internet et le Web Réseau informatique TIC TC - IUT Montpellier Internet et le Web Ensemble d'ordinateurs reliés entre eux et échangeant des informations sous forme de données numériques But : Rendre disponible l information

Plus en détail

Dans nos locaux au 98 Route de Sauve 30900 NÎMES. Un ordinateur PC par stagiaire, scanner, imprimante/copieur laser couleur

Dans nos locaux au 98 Route de Sauve 30900 NÎMES. Un ordinateur PC par stagiaire, scanner, imprimante/copieur laser couleur FORMATION FORFAIT WEB DEVELOPPEUR Qualification ISQ OPQF Formacode 46 125 Certification de titre professionnel Web Designer + modules optionnels : Développement PHP/MySQL avancé, Web App, CMS e-boutique

Plus en détail

TP 5 Les CMS, la forme et le fond Internet et Outils (IO2)

TP 5 Les CMS, la forme et le fond Internet et Outils (IO2) TP 5 Les CMS, la forme et le fond Internet et Outils (IO2) Un site, tel que vous avez appris à en programmer jusqu à maintenant, contenant un ensemble de pages HTML embellies de quelques feuilles de styles,

Plus en détail

Notes pour l utilisation d Expression Web

Notes pour l utilisation d Expression Web EICW Formation Webmaster Notes pour l utilisation d Expression Web G. Barmarin 2008-2009 1 /21 Table des matières 1 Introduction... 3 2 Installer Expression Web... 4 3 Explorer et personnaliser l interface

Plus en détail

Optimiser pour les appareils mobiles

Optimiser pour les appareils mobiles chapitre 6 Optimiser pour les appareils mobiles 6.1 Créer un site adapté aux terminaux mobiles avec jquery Mobile... 217 6.2 Transformer son site mobile en application native grâce à PhoneGap:Build...

Plus en détail

Pack Fifty+ Normes Techniques 2013

Pack Fifty+ Normes Techniques 2013 Pack Fifty+ Normes Techniques 2013 Nos formats publicitaires par site 2 Normes techniques 2013 Display classique Pavé vidéo Footer Accueil panoramique Publi rédactionnel Quiz Jeu concours Emailing dédié

Plus en détail

RAPPORT AUDIT SEO. Élaboré à l'attention de : Monsieur Greber Élaboré par : Cédric Peinado

RAPPORT AUDIT SEO. Élaboré à l'attention de : Monsieur Greber Élaboré par : Cédric Peinado - RAPPORT AUDIT SEO Élaboré à l'attention de : Monsieur Greber Élaboré par : Cédric Peinado 17 septembre 2013 Table des matières Optimisation structurelle 2 Optimisation des standards, performances et

Plus en détail

Normes techniques 2011

Normes techniques 2011 Normes techniques 2011 Display classique Formats Livrables Footer p 2 p 3 p 4 Opérations spéciales Publi-rédactionnel Jeu concours Quiz Lien partenaire Habillage Accueil panoramique Sponsoring de rubrique

Plus en détail

Utilisation de l éditeur.

Utilisation de l éditeur. Utilisation de l éditeur. Préambule...2 Configuration du navigateur...3 Débloquez les pop-up...5 Mise en évidence du texte...6 Mise en évidence du texte...6 Mise en page du texte...7 Utilisation de tableaux....7

Plus en détail

Devenez un véritable développeur web en 3 mois!

Devenez un véritable développeur web en 3 mois! Devenez un véritable développeur web en 3 mois! L objectif de la 3W Academy est de former des petits groupes d élèves au développement de sites web dynamiques ainsi qu à la création d applications web

Plus en détail

Les sites Internet dynamiques. contact : Patrick VINCENT pvincent@erasme.org

Les sites Internet dynamiques. contact : Patrick VINCENT pvincent@erasme.org Les sites Internet dynamiques contact : Patrick VINCENT pvincent@erasme.org Qu est-ce qu un site Web? ensemble de pages multimédia (texte, images, son, vidéo, ) organisées autour d une page d accueil et

Plus en détail

Sana Sellami. sana.sellami@lsis.org Licence Professionnelle SIL 2011-2012

Sana Sellami. sana.sellami@lsis.org Licence Professionnelle SIL 2011-2012 Sana Sellami sana.sellami@lsis.org Licence Professionnelle SIL 2011-2012 Connaître les principales techniques pour la création de sites web Se familiariser avec les langages du web Rendre dynamique le

Plus en détail

FORMATION / CREATION DE SITE WEB / 4 JOURNEES Sessions Octobre 2006

FORMATION / CREATION DE SITE WEB / 4 JOURNEES Sessions Octobre 2006 I. INTRODUCTION 1. Présentation du formateur et des élèves 2. Historique internet : d'où ça vient a. Historique général : 3 étapes majeures 1. l'histoire de l'informatique débute en 1942 avec la première

Plus en détail

Initiation à html et à la création d'un site web

Initiation à html et à la création d'un site web Initiation à html et à la création d'un site web Introduction : Concevoir un site web consiste à définir : - l'emplacement où ce site sera hébergé - à qui ce site s'adresse - le design des pages qui le

Plus en détail

creer votre site internet en html/css

creer votre site internet en html/css 3 jours (21 heures) 1110 HT (Inter) 2670 HT (Intra) Toute personne (particulier ou professionnel) souhaitant créer son site Internet Créez son site Internet Assurez sa mise en ligne Gérer les mises à jour

Plus en détail

Introduction à Expression Web 2

Introduction à Expression Web 2 Introduction à Expression Web 2 Définitions Expression Web 2 est l éditeur HTML de Microsoft qui répond aux standard dew3c. Lorsque vous démarrez le logiciel Expression Web 2, vous avez le choix de créer

Plus en détail

mon site web via WordPress

mon site web via WordPress mon site web via WordPress Vocabulaire CMS : Content Management System WordPress fait partie de cette famille de logiciels destinés à la conception et à la mise à jour dynamique de sites Web ou d applications

Plus en détail

Magento. Magento. Réussir son site e-commerce. Réussir son site e-commerce BLANCHARD. Préface de Sébastien L e p e r s

Magento. Magento. Réussir son site e-commerce. Réussir son site e-commerce BLANCHARD. Préface de Sébastien L e p e r s Mickaël Mickaël BLANCHARD BLANCHARD Préface de Sébastien L e p e r s Magento Préface de Sébastien L e p e r s Magento Réussir son site e-commerce Réussir son site e-commerce Groupe Eyrolles, 2010, ISBN

Plus en détail

< Atelier 1 /> Démarrer une application web

< Atelier 1 /> Démarrer une application web MES ANNOTATIONS SONT EN ROUGE : Axel < Atelier 1 /> Démarrer une application web Microsoft France Tutorial Découverte de ASP.NET 2.0 Sommaire 1 INTRODUCTION... 3 1.1 CONTEXTE FONCTIONNEL... 3 1.2 CONTEXTE

Plus en détail

CREATION d UN SITE WEB (INTRODUCTION)

CREATION d UN SITE WEB (INTRODUCTION) CREATION d UN SITE WEB (INTRODUCTION) Environnement : World Wide Web : ordinateurs interconnectés pour l échange d informations ( de données) Langages : HTML (HyperText Markup Language) : langages pour

Plus en détail

Formation Webmaster : Création de site Web Initiation + Approfondissement

Formation Webmaster : Création de site Web Initiation + Approfondissement Contactez notre équipe commerciale au 09.72.37.73.73 Aix en Provence - Bordeaux - Bruxelles - Geneve - Lille - Luxembourg - Lyon - Montpellier - Nantes - Nice - Paris - Rennes - Strasbourg - Toulouse Formation

Plus en détail

RESPONSIVE WEB DESIGN

RESPONSIVE WEB DESIGN RESPONSIVE WEB DESIGN Une approche pour concevoir des sites Web adaptatifs et une occasion d'inciter les étudiants à consulter des cours responsives Ivan MADJAROV Arnaud FÉVRIER Comment consulte-t-on le

Plus en détail

Le logiciel de création de site internet IZISPOT est un outil très puissant et qui est assez simple après quelques temps d utilisation.

Le logiciel de création de site internet IZISPOT est un outil très puissant et qui est assez simple après quelques temps d utilisation. 1 Le logiciel de création de site internet IZISPOT est un outil très puissant et qui est assez simple après quelques temps d utilisation. Voici un mode opératoire qui vous guidera dans l utilisation de

Plus en détail

LANGAGUE JAVA. Public Développeurs souhaitant étendre leur panel de langages de programmation

LANGAGUE JAVA. Public Développeurs souhaitant étendre leur panel de langages de programmation ING 01 LANGAGUE JAVA Durée : 21 heures 1090 HT / jour Dates : à définir en 2012 Concevoir et développer des programmes en langage Java Comprendre le fonctionnement de la machine virtuelle S approprier

Plus en détail

www.evogue.fr SUPPORT DE COURS / HTML

www.evogue.fr SUPPORT DE COURS / HTML L i a m T A R D I E U www.evogue.fr SUPPORT DE COURS / HTML Sommaire Sommaire... 2 Présentation... 3 Introduction... 3 Fonctionnement... 3 Historique... 4 Navigateurs... 6 Définition... 6 Historiquement...

Plus en détail

INTRODUCTION AU CMS MODX

INTRODUCTION AU CMS MODX INTRODUCTION AU CMS MODX Introduction 1. Créer 2. Organiser 3. Personnaliser UNE PETITE INTRODUCTION QUEST-CE QU UN CMS? CMS est l acronyme de Content Management System. C est outil qui vous permet de

Plus en détail

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

INTRODUCTION A JAVA. Fichier en langage machine Exécutable INTRODUCTION A JAVA JAVA est un langage orienté-objet pur. Il ressemble beaucoup à C++ au niveau de la syntaxe. En revanche, ces deux langages sont très différents dans leur structure (organisation du

Plus en détail

Autour du web. Une introduction technique Première partie : HTML. Georges-André SILBER Centre de recherche en informatique MINES ParisTech

Autour du web. Une introduction technique Première partie : HTML. Georges-André SILBER Centre de recherche en informatique MINES ParisTech Autour du web Une introduction technique Première partie : HTML Georges-André SILBER Centre de recherche en informatique MINES ParisTech silber@cri.ensmp.fr http://www.cri.ensmp.fr/people/silber/cours/2010/web

Plus en détail

<Créer un site Web. avec/> Suzanne Harvey

<Créer un site Web. avec/> Suzanne Harvey aire l o c s texte n o c le Dans Suzanne Harvey Conseillère pédagogique en informatique Service local du RÉCIT Commission scolaire de Saint-Hyacinthe Québec, Canada suzanne.harvey@prologue.qc.ca

Plus en détail

3. RÉALISATION ET QUALIFICATION D UN PROTOTYPE 3.1 Réalisation d un prototype CRÉATION D UNE PAGE WEB STATIQUE AU FORMAT HTML

3. RÉALISATION ET QUALIFICATION D UN PROTOTYPE 3.1 Réalisation d un prototype CRÉATION D UNE PAGE WEB STATIQUE AU FORMAT HTML Page:1/20 CRÉATION D UNE PAGE WEB STATIQUE AU FORMAT HTML Objectifs de l activité pratique : Notions sur le HTML, le WEB et le W3C Créer une page web statique au format HTML : - les marqueurs ou balises

Plus en détail

Publier dans la Base Documentaire

Publier dans la Base Documentaire Site Web de l association des ingénieurs INSA de Lyon Publier dans la Base Documentaire Remarque : la suppression des contributions n est pas possible depuis le Front-Office. lbuisset Page 1 18/09/2008

Plus en détail

Groupe Eyrolles, 2003, ISBN : 2-212-11317-X

Groupe Eyrolles, 2003, ISBN : 2-212-11317-X Groupe Eyrolles, 2003, ISBN : 2-212-11317-X 3 Création de pages dynamiques courantes Dans le chapitre précédent, nous avons installé et configuré tous les éléments indispensables à la mise en œuvre d une

Plus en détail

COMMENT PUBLIER SUR ARIANE?

COMMENT PUBLIER SUR ARIANE? COMMENT PUBLIER SUR ARIANE? Rédacteur : Dr Michel Arnould 1. SOMMAIRE 1.Sommaire...1 2.Connexion...1 3.Gestion des pages du wiki...1 Ajouter une nouvelle page...1 Supprimer, renommer, protéger une page...1

Plus en détail

Spétechs Mobile. Octobre 2013

Spétechs Mobile. Octobre 2013 Spétechs Mobile Octobre 2013 Appli ios Appli Android Site Mobile Les clicks URL Appli ios Créa en dur HTML5 Créa en dur Banner Interstitiel Interstitiel Vidéo Bouncing / traveling Image Bouncing / traveling

Plus en détail

INFORMATIQUE & WEB. PARCOURS CERTIFICAT PROFESSIONNEL Programmation de sites Web. 1 an 7 MODULES. Code du diplôme : CP09

INFORMATIQUE & WEB. PARCOURS CERTIFICAT PROFESSIONNEL Programmation de sites Web. 1 an 7 MODULES. Code du diplôme : CP09 INFORMATIQUE & WEB Code du diplôme : CP09 Passionné par l informatique et le web, vous souhaitez obtenir une certification dans un domaine porteur et enrichir votre CV? PARCOURS CERTIFICAT PROFESSIONNEL

Plus en détail

Intégrateur Web HTML5 CSS3

Intégrateur Web HTML5 CSS3 Intégrateur Web HTML5 CSS3 L objectif de la 3W Academy est de former des petits groupes d élèves à l intégration de sites internet ainsi qu à la création d applications web simples telles qu un blog ou

Plus en détail

145A, avenue de Port Royal, Bonaventure (Québec) G0C 1E0 Sans frais : 1 888 765 4636 www.solutioninfomedia.com

145A, avenue de Port Royal, Bonaventure (Québec) G0C 1E0 Sans frais : 1 888 765 4636 www.solutioninfomedia.com Guide de l utilisateur CMS 1 Navigation dans le CMS... 2 1.1 Menu principal... 2 1.2 Modules tableau... 3 1.3 Modules formulaire... 5 1.4 Navigation dans le site Web en mode édition... 6 2 Utilisation

Plus en détail

Langage HTML (2 partie) <HyperText Markup Language> <tv>lt La Salle Avignon BTS IRIS</tv>

Langage HTML (2 partie) <HyperText Markup Language> <tv>lt La Salle Avignon BTS IRIS</tv> Langage HTML (2 partie) «Je n'ai fait que prendre le principe d - hypertexte et le relier au principe du TCP et du DNS et alors boum! ce fut le World Wide Web!» Tim Berners-Lee

Plus en détail

Echosgraphik. Ce document sert uniquement à vous donner une vision sur ma manière de travailler et d appréhender un projet

Echosgraphik. Ce document sert uniquement à vous donner une vision sur ma manière de travailler et d appréhender un projet Echosgraphik Ce document sert uniquement à vous donner une vision sur ma manière de travailler et d appréhender un projet Présentation I. Echosgraphik Protocoles de travail I. Développement du site II.

Plus en détail

Publier un Carnet Blanc

Publier un Carnet Blanc Site Web de l association des ingénieurs INSA de Lyon Publier un Carnet Blanc Remarque : la suppression des contributions n est pas possible depuis le Front-Office. lbuisset Page 1 18/09/2008 Publication,

Plus en détail

Formation : WEbMaster

Formation : WEbMaster Formation : WEbMaster Objectif et Description : Centre Eclipse vous propose une formation complète WebMaster, vous permettant de : Utiliser dès maintenant les nouveautés du web2, ainsi alléger les besoins

Plus en détail

Technologies du Web. Créer et héberger un site Web. Pierre Senellart. Page 1 / 26 Licence de droits d usage

Technologies du Web. Créer et héberger un site Web. Pierre Senellart. Page 1 / 26 Licence de droits d usage Technologies du Web Créer et héberger un site Web Page 1 / 26 Plan Planification Choisir une solution d hébergement Administration Développement du site Page 2 / 26 Cahier des charges Objectifs du site

Plus en détail

FileMaker Server 11. Publication Web personnalisée avec XML et XSLT

FileMaker Server 11. Publication Web personnalisée avec XML et XSLT FileMaker Server 11 Publication Web personnalisée avec XML et XSLT 2007-2010 FileMaker, Inc. Tous droits réservés. FileMaker, Inc. 5201 Patrick Henry Drive Santa Clara, Californie 95054 FileMaker est une

Plus en détail

Spétechs Mobile. D e r n i è r e m i s e à j o u r : a o û t 2014

Spétechs Mobile. D e r n i è r e m i s e à j o u r : a o û t 2014 Spétechs Mobile D e r n i è r e m i s e à j o u r : a o û t 2014 Généralités Envoi des créas à Amandine Canu, responsable traffic mobile : acanu@hi-media.com Mettre en copie de votre e-mail votre contact

Plus en détail

Bureautique Initiation Excel-Powerpoint

Bureautique Initiation Excel-Powerpoint Module de Formation Personnalisée : Bureautique Initiation Excel-Powerpoint Durée : jours ouvrables Prix : Formation personnalisée en vue d obtenir les notions de base indispensables pour : Excel Office

Plus en détail

KompoZer. Composition du site : _ une page d'accueil : index.html. _ une page pour la théorie : theorie.html. _ une page pour les photos : photos.

KompoZer. Composition du site : _ une page d'accueil : index.html. _ une page pour la théorie : theorie.html. _ une page pour les photos : photos. KompoZer Créer un site «simple» Composition du site : _ une page d'accueil : index.html _ une page pour la théorie : theorie.html _ une page pour les photos : photos.html _ une page avec la galerie : galerie.html

Plus en détail

Créer un site Web : mode d emploi Sous SPIP, avec le squelette «établissement» de l académie de Versailles

Créer un site Web : mode d emploi Sous SPIP, avec le squelette «établissement» de l académie de Versailles Mission TICE - académie de Versailles 7 nov. 2008 Créer un site Web : mode d emploi Sous SPIP, avec le squelette «établissement» de l académie de Versailles Anne-Cécile Franc Mission TICE académie de Versailles

Plus en détail

1. La notion de cascade

1. La notion de cascade HTML 5 et CSS 3 (partie 2) Objectifs Connaître quelques notions avancées de CSS 3, Appréhender l affichage, Introduction au Responsive Web Design. 1. La notion de cascade On constate que l on peut avoir

Plus en détail

Module BD et sites WEB

Module BD et sites WEB Module BD et sites WEB Cours 8 Bases de données et Web Anne Doucet Anne.Doucet@lip6.fr 1 Le Web Architecture Architectures Web Client/serveur 3-tiers Serveurs d applications Web et BD Couplage HTML-BD

Plus en détail

Auteur LARDOUX Guillaume Contact guillaume.lardoux@epitech.eu Année 2014 DEVELOPPEMENT MOBILE AVEC CORDOVA

Auteur LARDOUX Guillaume Contact guillaume.lardoux@epitech.eu Année 2014 DEVELOPPEMENT MOBILE AVEC CORDOVA Auteur LARDOUX Guillaume Contact guillaume.lardoux@epitech.eu Année 2014 DEVELOPPEMENT MOBILE AVEC CORDOVA Sommaire 1. Introduction 2. Installation 3. Fonctionnement 4. Développement 5. Démonstration 2

Plus en détail

Introduction à HTML5, CSS3 et au responsive web design

Introduction à HTML5, CSS3 et au responsive web design 1 Introduction à HTML5, CSS3 et au responsive web design Jusqu à une période récente, les sites web étaient conçus avec une largeur fixe de l ordre de 960 pixels, en espérant que les visiteurs en tirent

Plus en détail

les techniques d'extraction, les formulaires et intégration dans un site WEB

les techniques d'extraction, les formulaires et intégration dans un site WEB les techniques d'extraction, les formulaires et intégration dans un site WEB Edyta Bellouni MSHS-T, UMS838 Plan L extraction des données pour un site en ligne Architecture et techniques Les différents

Plus en détail

WEB & DÉVELOPPEMENT LES BASES DU WEB LE LANGAGE HTML FEUILLES DE STYLES CSS HISTORIQUE D INTERNET ET DU WEB LES DIFFÉRENTS LANGAGES

WEB & DÉVELOPPEMENT LES BASES DU WEB LE LANGAGE HTML FEUILLES DE STYLES CSS HISTORIQUE D INTERNET ET DU WEB LES DIFFÉRENTS LANGAGES WEB & DÉVELOPPEMENT LES BASES DU WEB HISTORIQUE D INTERNET ET DU WEB LES DIFFÉRENTS LANGAGES LE LANGAGE HTML STRUCTURE D UNE PAGE En-tête et corps Syntaxe INSÉRER DES CONTENUS Texte : formatage (titre,

Plus en détail

Media queries : gérer différentes zones de visualisation

Media queries : gérer différentes zones de visualisation 2 Media queries : gérer différentes zones de visualisation Comme nous l avons vu au chapitre précédent, les CSS3 sont constituées de modules. Media queries est simplement l un d eux. Ce module permet d

Plus en détail

NFA016 : Introduction. Pour naviguer sur le Web, il faut : Naviguer: dialoguer avec un serveur web

NFA016 : Introduction. Pour naviguer sur le Web, il faut : Naviguer: dialoguer avec un serveur web NFA016 : Introduction O. Pons, S. Rosmorduc Conservatoire National des Arts & Métiers Pour naviguer sur le Web, il faut : 1. Une connexion au réseau Réseau Connexion physique (câbles,sans fils, ) à des

Plus en détail

1. La plate-forme LAMP

1. La plate-forme LAMP Servi ces pour intranet et Internet Ubuntu Linux - Création et gestion d un réseau local d entreprise 1. La plate-forme LAMP Services pour intranet et Internet La fourniture d'un site pour le réseau ou

Plus en détail

SII Stage d informatique pour l ingénieur

SII Stage d informatique pour l ingénieur SII Stage d informatique pour l ingénieur Création d un site Web École nationale supérieure de techniques avancées SII Stage d informatique pour l ingénieur 1 / 15 L informatique et le temps qui passe...

Plus en détail

Optimiser les e-mails marketing Les points essentiels

Optimiser les e-mails marketing Les points essentiels Optimiser les e-mails marketing Les points essentiels Sommaire Une des clés de succès d un email marketing est la façon dont il est créé puis intégré en HTML, de telle sorte qu il puisse être routé correctement

Plus en détail

25 mars. Tutoriel sur Laravel. Préparé par : Lydiane Beaulne-Bélisle. Ceci est un tutorial qui montre comment débuter avec le Framework PHP Laravel.

25 mars. Tutoriel sur Laravel. Préparé par : Lydiane Beaulne-Bélisle. Ceci est un tutorial qui montre comment débuter avec le Framework PHP Laravel. 25 mars Tutoriel sur Laravel Préparé par : Lydiane Beaulne-Bélisle Ceci est un tutorial qui montre comment débuter avec le Framework PHP Laravel. Créé pour le cours de Projet de fin d étude Collège de

Plus en détail

Stage «Créer et animer un site Web en équipe»

Stage «Créer et animer un site Web en équipe» Stage «Créer et animer un site Web en équipe» EREA Jean Isoard - Montgeron Jour 1 21/12/2012 Réaliser un site web Pour quoi faire? Publier sur le Web réaliser un journal en ligne (blog) écrire une ou plusieurs

Plus en détail

Diffuser un contenu sur Internet : notions de base... 13

Diffuser un contenu sur Internet : notions de base... 13 Diffuser un contenu sur Internet : notions de base... 13 1.1 Coup d œil sur l organisation de cet ouvrage.............. 15 Préambule : qu est-ce qu une page web?................ 16 À propos du HTML...........................

Plus en détail

FileMaker Server 12. publication Web personnalisée avec XML

FileMaker Server 12. publication Web personnalisée avec XML FileMaker Server 12 publication Web personnalisée avec XML 2007-2012 FileMaker, Inc. Tous droits réservés. FileMaker, Inc. 5201 Patrick Henry Drive Santa Clara, California 95054 FileMaker et Bento sont

Plus en détail

BES WEBDEVELOPER ACTIVITÉ RÔLE

BES WEBDEVELOPER ACTIVITÉ RÔLE BES WEBDEVELOPER ACTIVITÉ Le web developer participe aux activités concernant la conception, la réalisation, la mise à jour, la maintenance et l évolution d applications internet/intranet statiques et

Plus en détail

HTML5 et CSS3 pour des sites Responsive Web Design

HTML5 et CSS3 pour des sites Responsive Web Design Chapitre 1 : Introduction A. Le design Web aujourd'hui 11 B. Le Responsive Web Design 11 C. Les approches dans la conception 12 D. Le lâcher-prise 12 E. Les objectifs du livre 13 F. Les outils de l intégrateur

Plus en détail

02/02/2011. test 1. Communication visuelle & web. Pao. Principes fondamentaux. Les six principes de base. La mise en page. Module sur trois journées

02/02/2011. test 1. Communication visuelle & web. Pao. Principes fondamentaux. Les six principes de base. La mise en page. Module sur trois journées Communication visuelle & web Module sur trois journées 1, 5 jour : communication print & visuelle 1.5 jour : communication web mise en pratique evaluation sur QCM Vous serez en mesure participer à la conception

Plus en détail

Programmation Web. Madalina Croitoru IUT Montpellier

Programmation Web. Madalina Croitoru IUT Montpellier Programmation Web Madalina Croitoru IUT Montpellier Organisation du cours 4 semaines 4 ½ h / semaine: 2heures cours 3 ½ heures TP Notation: continue interrogation cours + rendu à la fin de chaque séance

Plus en détail

RESUME DE CARRIERE. Alice JULIENNE. 23 ans Nationalité Française Développeur Web Front-End. Compétences

RESUME DE CARRIERE. Alice JULIENNE. 23 ans Nationalité Française Développeur Web Front-End. Compétences RESUME DE CARRIERE Alice JULIENNE 23 ans Nationalité Française Développeur Web Front-End Compétences Systèmes Langages Windows (XP, 98) Macintosh OS X HTML, XHTML, CSS, XML, PHP, SQL, Javascript, J-Querry

Plus en détail

Internet. DNS World Wide Web. Divers. Mécanismes de base Exécution d'applications sur le web. Proxy, fire-wall

Internet. DNS World Wide Web. Divers. Mécanismes de base Exécution d'applications sur le web. Proxy, fire-wall Internet DNS World Wide Web Mécanismes de base Exécution d'applications sur le web Divers Proxy, fire-wall 1 Les services usuels de l Internet Services principaux (applications) disponibles sur l Internet

Plus en détail

RESPONSIVE DESIGN : Comment offrir à vos sites une adaptabilité parfaite?

RESPONSIVE DESIGN : Comment offrir à vos sites une adaptabilité parfaite? RESPONSIVE DESIGN : Comment offrir à vos sites une adaptabilité parfaite? Medialibs, votre partenaire digital Quoi? Un partenaire pour une gestion globale du digital (un laboratoire R&D, éditeur de logiciels

Plus en détail

Théorie : internet, comment ça marche?

Théorie : internet, comment ça marche? Théorie : internet, comment ça marche? L histoire d internet 1969 Tout débute aux Etats-Unis. Les soviétiques ont lancé leur satellite Spoutnik en 1957 et les américains ont peur d une guerre nucléaire.

Plus en détail

Spétechs Mobile. D e r n i è r e m i s e à j o u r : s e p t e m b r e 2 0 1 4

Spétechs Mobile. D e r n i è r e m i s e à j o u r : s e p t e m b r e 2 0 1 4 Spétechs Mobile D e r n i è r e m i s e à j o u r : s e p t e m b r e 2 0 1 4 Généralités Envoi des créas à Amandine Canu, responsable traffic mobile : acanu@hi-media.com Mettre en copie de votre e-mail

Plus en détail

TP JAVASCRIPT OMI4 TP5 SRC1 2011-2012

TP JAVASCRIPT OMI4 TP5 SRC1 2011-2012 TP JAVASCRIPT OMI4 TP5 SRC1 2011-2012 FORMULAIRE DE CONTACT POUR PORTFOLIO PRINCIPE GENERAL Nous souhaitons réaliser un formulaire de contact comprenant les champs suivants : NOM PRENOM ADRESSE MAIL MESSAGE

Plus en détail

Services bancaires par Internet aux entreprises. Guide pratique pour : Rapports de solde Version 8.05.22

Services bancaires par Internet aux entreprises. Guide pratique pour : Rapports de solde Version 8.05.22 Services bancaires par Internet aux entreprises Guide pratique pour : Rapports de solde Version 8.05.22 Table des matières Avez-vous besoin d aide?... 3 Exigences informatiques... 4 Navigateurs acceptés...

Plus en détail

La mémorisation des mots de passe dans les navigateurs web modernes

La mémorisation des mots de passe dans les navigateurs web modernes 1 La mémorisation des mots de passe dans les navigateurs web modernes Didier Chassignol Frédéric Giquel 6 décembre 2005 - Congrès JRES 2 La problématique Multiplication des applications web nécessitant

Plus en détail

{less} Guide de démarrage

{less} Guide de démarrage {less Guide de démarrage Pré requis L'utilisation d'un pré processeur css nécessite son installation préalable. Vous pouvez choisir de tout installer du coté du serveur ou du coté du client. Votre site

Plus en détail

MAILING KOMPOZER... 2 CREEZ UNE PAGE... 2 FORMAT DE LA PAGE... 2 AJOUTER DU TEXTE SUR UNE PAGE... 4

MAILING KOMPOZER... 2 CREEZ UNE PAGE... 2 FORMAT DE LA PAGE... 2 AJOUTER DU TEXTE SUR UNE PAGE... 4 MAILING Table des matières KOMPOZER... 2 CREEZ UNE PAGE... 2 FORMAT DE LA PAGE... 2 AJOUTER DU TEXTE SUR UNE PAGE... 4 INSERER UNE IMAGE (OU UNE PHOTO) PAS DE COPIER / COLLER... 5 INSERER UN TABLEAU...

Plus en détail

Utiliser un CMS: Wordpress

Utiliser un CMS: Wordpress Utiliser un CMS: Wordpress Annie Danzart Annie.Danzart@telecom-paristech.fr Wordpress Concevoir un site web statique Concevoir un site web dynamique Choisir un hébergement Choix du CMS Wordpress: installation

Plus en détail

Sommaire : Pourquoi créer un site web? Qu est-ce qu un site Web? Les différents types de sites. Quelles solutions peuvent être employées?

Sommaire : Pourquoi créer un site web? Qu est-ce qu un site Web? Les différents types de sites. Quelles solutions peuvent être employées? Sommaire : Pourquoi créer un site web? Qu est-ce qu un site Web? Les différents types de sites Quelles solutions peuvent être employées? Présentation d une des solutions Conclusion Aujourd hui le web est

Plus en détail

Programmation Web. Introduction

Programmation Web. Introduction Programmation Web Introduction 1 Introduction 10 séances 1 h cours + 1h TD Notes : contrôle continu DS 1 TP : note de groupe : rapport + code source + démo TD : note personnelle (=0 si 2 absences non justifiées)

Plus en détail

Tapez le titre de la page «BASTIA ville méditerranéenne», puis allez deux fois à la ligne à l aide de la touche Entrée.

Tapez le titre de la page «BASTIA ville méditerranéenne», puis allez deux fois à la ligne à l aide de la touche Entrée. Créer un site Internet à l aide du logiciel NVU Le logiciel NVU, permet l édition Wysiwyg (What You See, Is What You Get, ce que vous voyez, est ce que vous obtenez ) d un site internet. Vous rédigez le

Plus en détail

UN SITE WEB RESPONSIVE EN UNE HEURE?

UN SITE WEB RESPONSIVE EN UNE HEURE? UN SITE WEB RESPONSIVE EN UNE HEURE?! O N O R H C P TO Raphaël Goetter Raphaël Goetter alsacreations.fr alsacreations.com goetter.fr knacss.com mobitest.me @goetter EN UNE HEURE, VOUS AVEZ DIT?!? R E N

Plus en détail