Système d`Information Partie II Programmation en PHP
Transcription
Système d`Information Partie II Programmation en PHP
Système d’Information Partie II Programmation en PHP http://www.agroparistech.fr/Systeme-d-Information Laurent Orseau UFR d’Informatique Département MMIP [email protected] AgroParisTech Grignon 1A Année 2014-2015 2 Table des matières 1 Introduction au PHP 1.1 Bases de la programmation . . . . . . . . . . . . . . 1.2 Premier programme . . . . . . . . . . . . . . . . . . 1.2.1 Notion d’exécution . . . . . . . . . . . . . . 1.3 Valeurs et types . . . . . . . . . . . . . . . . . . . . 1.3.1 Opérateurs, opérandes, opérations et résultats 1.3.2 La fonction infos_expr . . . . . . . . . . . . 1.3.3 Conversions de types . . . . . . . . . . . . . 1.4 Expressions et réduction d’expressions . . . . . . . . 1.5 Variables . . . . . . . . . . . . . . . . . . . . . . . 1.5.1 Affectation de valeur à une variable . . . . . 1.5.2 Autres opérateurs d’affectations . . . . . . . 1.5.3 Conventions et nom de variables . . . . . . . 1.6 Notion de bloc d’instructions . . . . . . . . . . . . . 1.7 Structures de contrôle . . . . . . . . . . . . . . . . . 1.8 La condition if . . . . . . . . . . . . . . . . . . . . . 1.8.1 Utilisation du else . . . . . . . . . . . . . . 1.8.2 Imbrication des conditions . . . . . . . . . . 1.9 Les fonctions . . . . . . . . . . . . . . . . . . . . . 1.9.1 Un premier exemple . . . . . . . . . . . . . 1.9.2 Variables locales . . . . . . . . . . . . . . . 1.9.3 Arguments multiples . . . . . . . . . . . . . 1.9.4 Valeur de retour . . . . . . . . . . . . . . . . 1.9.5 Valeur par défaut . . . . . . . . . . . . . . . 1.9.6 Forme générale d’une fonction . . . . . . . . 1.9.7 Plusieurs fonctions . . . . . . . . . . . . . . 1.9.8 Signatures simplifiées . . . . . . . . . . . . 1.9.9 Avantages de l’utilisation de fonctions . . . . 1.10 La boucle while . . . . . . . . . . . . . . . . . . . . 1.10.1 Imbrications . . . . . . . . . . . . . . . . . 1.11 La boucle do...while . . . . . . . . . . . . . . . . . . 1.12 La boucle for . . . . . . . . . . . . . . . . . . . . . 1.13 Tableaux . . . . . . . . . . . . . . . . . . . . . . . . 3 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 7 7 9 9 10 12 13 13 15 15 17 18 18 19 19 20 20 23 23 26 29 30 33 34 35 35 36 37 39 39 40 42 1.13.1 Parcours en boucle . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.2 La boucle foreach . . . . . . . . . . . . . . . . . . . . . . . . . . 1.13.3 Tableaux associatifs . . . . . . . . . . . . . . . . . . . . . . . . 2 3 4 Le paquetage AgroSIXPack 2.1 Introduction . . . . . . . . . . . . . . . . . . 2.2 Installation et utilisation . . . . . . . . . . . 2.3 Affichage . . . . . . . . . . . . . . . . . . . 2.4 Formulaires : Interaction avec l’utilisateur . . 2.4.1 Création et affichage de formulaires . 2.4.2 Traitement des données de formulaire 2.5 Sessions . . . . . . . . . . . . . . . . . . . . 2.6 Modification du style . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PHP/MySQL 3.1 Connexion à la base de données . . . . . . . . . . . . . . . . 3.1.1 Exécution de requêtes SQL . . . . . . . . . . . . . . . 3.1.2 Requêtes de type SELECT . . . . . . . . . . . . . . . 3.1.3 Autres types requêtes . . . . . . . . . . . . . . . . . . 3.1.4 Requêtes paramétrées : Échappement des apostrophes 3.2 Fermeture de la connexion à la base . . . . . . . . . . . . . . 3.3 Exemple complet . . . . . . . . . . . . . . . . . . . . . . . . 3.4 Autres fonctions utiles . . . . . . . . . . . . . . . . . . . . . 3.4.1 Chaîne en SQL . . . . . . . . . . . . . . . . . . . . . 3.4.2 Noms et identifiants dans une liste déroulante . . . . . 3.5 Pour aller plus loin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Travaux Dirigés PHP TD 1 : Valeurs, expressions, variables, conditionnelle . . . . . . . . . Exercice 1 : Premiers pas avec l’évaluateur . . . . . . . . . . . . Exercice 2 : Premiers pas . . . . . . . . . . . . . . . . . . . . . Exercice 3 : Types et expressions . . . . . . . . . . . . . . . . . Exercice 4 : Variables et affectations . . . . . . . . . . . . . . . Exercice 5 : Conditionnelle . . . . . . . . . . . . . . . . . . . . Exercice 6 : [Bonus] Diviseurs . . . . . . . . . . . . . . . . . . TD 2 : Fonctions et variables . . . . . . . . . . . . . . . . . . . . . . Exercice 1 : Premier programme . . . . . . . . . . . . . . . . . Exercice 2 : Correction d’erreurs . . . . . . . . . . . . . . . . . Exercice 3 : Fonction de concaténation de chaînes de caractères . Exercice 4 : Fonctions . . . . . . . . . . . . . . . . . . . . . . . Exercice 5 : Variables locales . . . . . . . . . . . . . . . . . . . Exercice 6 : Multilinguisme . . . . . . . . . . . . . . . . . . . . TD 3 : Boucles . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 43 44 . . . . . . . . 46 46 46 47 51 51 58 62 63 . . . . . . . . . . . 66 66 67 67 69 69 70 70 72 72 73 73 . . . . . . . . . . . . . . . 74 75 75 75 75 77 78 79 81 81 81 82 83 83 84 86 5 Exercice 1 : 99 Bouteilles de bière . . Exercice 2 : Triangle . . . . . . . . . TD 4 : Tableaux et boucles . . . . . . . . . Exercice 1 : Manipulation de tableaux Exercice 2 : Jeux de mots . . . . . . . Exercice 3 : [Bonus] Vente en ligne . TD 5 : Formulaires 1 . . . . . . . . . . . . Exercice 1 : Formulaires . . . . . . . TD 6 : Formulaires 2 et Sessions . . . . . . Exercice 1 : ADN . . . . . . . . . . . Exercice 2 : Compteur . . . . . . . . Exercice 3 : [Bonus] Blackjack . . . . TD 7 : PHP/MySQL . . . . . . . . . . . . Exercice 1 : Les Simpson . . . . . . . TD 8 : [Bonus] Labyrinthe . . . . . . . . . TD 9 : [Bonus] Réseau social . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A PHP : Addendum A.1 Quelques fonctions et structures supplémentaires . . . . . . . . . A.1.1 Tests de types . . . . . . . . . . . . . . . . . . . . . . . . A.1.2 print_r . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.1.3 rand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.1.4 include . . . . . . . . . . . . . . . . . . . . . . . . . . . A.1.5 break . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.1.6 isset . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.1.7 array_key_exists . . . . . . . . . . . . . . . . . . . . . . A.1.8 unset . . . . . . . . . . . . . . . . . . . . . . . . . . . . A.1.9 str_split . . . . . . . . . . . . . . . . . . . . . . . . . . . A.2 Chaînes de caractères . . . . . . . . . . . . . . . . . . . . . . . . A.2.1 Guillemets simples et doubles, échappement de guillemet A.3 Variables globales . . . . . . . . . . . . . . . . . . . . . . . . . . A.4 Gestion des erreurs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86 86 90 90 91 94 96 96 100 100 103 103 106 106 108 111 . . . . . . . . . . . . . . 112 112 112 113 113 114 114 114 114 114 115 115 115 116 117 B Indentation en PHP 118 C Ressources et aide en ligne 120 D Utiliser Notepad++, PHP et MySQL chez vous D.1 Éditeur de texte : Notepad++ . . . . . . . . D.2 Navigateur : Firefox . . . . . . . . . . . . . D.3 Serveur Apache/Base de données : EasyPHP D.3.1 Configuration d’EasyPHP . . . . . D.4 Paquetage AgroSIXPack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 121 121 121 122 122 Chapitre 1 Introduction au PHP Que ce soit dans un régulateur de chauffage, dans un téléphone portable, dans une montre, dans une voiture, dans une machine agricole ou bien sûr dans un ordinateur, dès qu’il y a un peu d’électronique, il y a de la programmation. Tout logiciel (tableurs, jeux, logiciels de gestion et comptabilité, de traitement de texte, etc.) a été programmé. La plupart du temps, les logiciels sont suffisamment bien faits pour que l’on n’ait pas à savoir programmer. Mais comprendre la manière dont un ordinateur fonctionne est un atout important pour n’importe quel utilisateur. Du fait de l’omniprésence actuelle des ordinateurs, connaître la programmation (sans avoir besoin de la maîtriser) est aujourd’hui une nécessité, surtout pour un ingénieur, quelque soit sa discipline. Car savoir programmer c’est pouvoir demander à la machine de faire des tâches répétitives automatiquement, beaucoup plus rapidement, avec une plus grande fiabilité, pour un minimum de coût. Il est alors possible de déléguer à l’ordinateur toutes sortes de tâches fastidieuses, permettant un gain de temps et d’énergie, et ainsi aussi de se focaliser sur des tâches plus importantes. Similairement aux langages humains, un langage de programmation est un outil de communication, permettant au programmeur de dialoguer avec l’ordinateur avec une grammaire, une syntaxe et un vocabulaire que les deux parties comprennent. En 1994, Rasmus Lerdorf a créé le langage PHP (pour "PHP : Hypertext Preprocessor") pour gérer son propre site Web. PHP s’avéra fort utile et de nombreuses personnes commencèrent à l’utiliser. Il existe d’autres langages pour la création de sites Web dynamiques, comme Java, l’ASP, etc. Les avantages du PHP sont qu’il est libre 1 et gratuit, aujourd’hui très répandu, et assez facile d’utilisation, tout en restant relativement complet, et permet notamment un interfaçage simple avec des bases de données. Le PHP est un langage de programmation au même titre que Matlab, C, Python ou Java, avec lesquels il partage de nombreux points communs. Sa particularité est d’être très pratique pour créer des sites Web ; cependant nous l’utiliserons comme simple outil de programmation, l’aspect "site Web" ne nous intéressant que pour obtenir un rendu visuel. Nous n’apprendrons donc pas à créer un site Web 2 . De par les nombreuses similitudes et 1. Ce qui signifie principalement qu’on a le droit de l’utiliser, de le modifier et de le redistribuer librement, mais attention cependant à bien lire les termes de la licence. 2. De nombreux systèmes de gestion de contenu existent et sont bien plus adaptés pour cette tâche : 6 1.1. BASES DE LA PROGRAMMATION 7 les bases communes entre PHP et d’autres langages de programmation (C, Java, Python, BASIC, Pascal, Lisp, . . .), apprendre l’un d’entre eux correctement permettra par la suite l’acquisition d’un autre langage avec une grande facilité, si vous en aviez le besoin. Nous commencerons par voir les bases de la programmation en PHP, à travers les expressions, les variables, les fonctions, les boucles et les tableaux. Ensuite nous détaillerons le paquetage AgroSIXPack qui permet de s’abstraire de l’aspect technique et pédagogiquement peu intéressant dans ce cours de la création de site Web et de l’interface utilisateur, pour se concentrer sur l’aspect programmation. Enfin, nous utiliserons PHP avec MySQL pour effectuer des requêtes sur une base de données. 1.1 Bases de la programmation La plupart des langages de programmation possèdent les éléments suivants : — des valeurs et des expressions qui sont des “calculs” sur ces valeurs, — des variables, permettant de stocker des valeurs, — des tableaux ou des listes, qui sont une succession de variables que l’on peut parcourir automatiquement, — des branchements conditionnels, permettant d’effectuer certaines instructions selon la valeur de certaines variables, — des boucles d’itération, permettant d’effectuer un même bloc d’instructions plusieurs fois de suite, jusqu’à ce qu’une condition d’arrêt soit vérifiée, — des fonctions, qui permettent entre autres d’éviter d’écrire plusieurs fois les mêmes choses. — un certain nombre de fonctions prédéfinies, permettant d’afficher des valeurs à l’écran, lire/écrire dans des fichiers, faire des calculs arithmétiques, etc., Être capable d’utiliser ces éléments, c’est être capable de programmer, peu importe le langage, quasiment. PHP possède ces éléments et nous les détaillerons un par un dans la suite. Nous commencerons par les valeurs et expressions, les variables et les fonctions, car ce sont les points les plus importants de la programmation. Une fois ces éléments bien acquis, le reste devrait sembler logique et donc facile à acquérir. 1.2 Premier programme Le code source d’un programme est un texte lisible à la fois par un humain et par l’ordinateur. Il s’agit d’une suite d’instructions que l’ordinateur exécutera de la même manière qu’une recette de cuisine, c’est-à-dire en lisant les lignes une par une, dans l’ordre, et en exécutant une action (ou plusieurs) à chaque ligne. Voici un tout premier programme PHP : http://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_contenu 8 1 2 3 4 5 6 CHAPITRE 1. INTRODUCTION AU PHP <?php function main() { // Message de bienvenue : printline(’Bonjour le monde !’); } ?> Ce programme, une fois exécuté sur l’ordinateur, affiche à l’écran : Bonjour le monde ! Remarquons plusieurs parties : <?php apparait toujours en début de programme et ?> toujours à la fin. Ces "balises" signifient qu’à l’intérieur il y a du code PHP. Si elles ne sont pas présentes, le texte n’est pas considéré comme du PHP et ne peut donc pas être exécuté. Nous déclarons ensuite la fonction main (pour fonction principale en anglais) dont la définition se trouve entre les accolades. Il est obligatoire de déclarer 3 cette fonction main. Dans la suite de ce chapitre, nous l’omettrons la plupart du temps pour nous concentrer sur l’important, sauf dans les exemples de programmes entiers ; de même, nous omettrons la plupart du temps les <?php ?>. À l’intérieur de la fonction main, une instruction fait appel à la fonction prédéfinie qui affiche à l’écran ce qui lui est donné en argument, dans les parenthèses, puis passe une ligne. Le texte à afficher à l’écran est écrit dans le programme avec des guillemets car cela permet à l’ordinateur de savoir qu’il ne faut pas chercher à interpréter ce qui est entre guillemets comme des instructions, mais de le considérer comme du texte simple, sans signification particulière pour le programme. printline, À la fin de l’instruction, il y a un point virgule " ;" pour signaler à l’ordinateur que l’instruction courante s’arrête là ; c’est un point de repère permettant de séparer les instructions. Le texte commençant par ’//’ est un commentaire, il n’est donc pas interprété par PHP, qui passe directement à la ligne suivante. On peut mettre plusieurs lignes de commentaires entre ’/*’ et ’*/’ : 1 2 3 4 5 6 7 // Commentaire sur une ligne /* Commentaire sur plusieurs lignes */ 3. À noter que l’obligation de déclarer une fonction main est due au paquetage AgroSIXPack, que nous détaillerons dans un prochain chapitre. 1.3. VALEURS ET TYPES 1.2.1 9 Notion d’exécution L’ordinateur, lorsqu’il reçoit une fichier PHP à exécuter, regarde chaque ligne l’une après l’autre. Chaque ligne de code comprend une ou plusieurs instructions que l’ordinateur exécute dans l’ordre. Le programme suivant : 1 2 3 4 5 6 <?php function main() { printline(’Bonjour le monde !’); printline(’Au revoir.’); } ?> affichera toujours : Bonjour le monde ! Au revoir. et jamais : Au revoir. Bonjour le monde ! Par la suite, nous suivrons le cours de l’exécution d’un programme PHP à l’aide d’un pointeur d’instruction. Ici, le pointeur d’instruction est tout d’abord positionné sur l’instruction de la ligne 3, c’est-à-dire la première instruction de la fonction main, laquelle est exécutée. Le pointeur se déplace ensuite sur l’instruction suivante, à la ligne 4, qui est alors aussi exécutée, et ainsi de suite dans l’ordre jusqu’à la fin du programme, c’està-dire jusqu’à atteindre l’accolade fermante de la fonction main. Cet ordre linéaire sera suivi la plupart du temps, mais de temps en temps le pointeur d’instruction “sautera” à une autre ligne. 1.3 Valeurs et types En PHP, comme dans de nombreux langages de programmation, les différentes valeurs que l’on peut manipuler sont de différents types. Voici les principaux types que nous allons utiliser. — Le type int (pour l’anglais integer, entier) correspond aux nombres entiers, comme 5 et -2. — Le type float correspond aux nombres à “virgule flottante”, c’est-à-dire simplement les nombres à virgule, bien qu’on utilise en réalité un point conformément à la notation anglo-saxonne, par exemple 3.14. — Le type string correspond aux chaînes de caractères, c’est-à-dire à du texte que l’on peut manipuler, que l’on note entouré de guillemets simples, comme par exemple ’ceci est une chaîne de caractères’ ou bien : ’un peu de texte, pour la forme.’ 10 CHAPITRE 1. INTRODUCTION AU PHP — Le type boolean 4 , abrégé en bool, correspond aux deux seules valeurs true et false. Il existe d’autres types que nous verrons plus tard, comme le type array pour les tableaux (cf. section 1.13), et le type ressource (cf. section 3). 1.3.1 Opérateurs, opérandes, opérations et résultats Une grande partie de ce qu’un programme fait est de manipuler des valeurs, c’està-dire prendre des valeurs d’entrée, les transformer en utilisant des opérateurs et des fonctions, pour produire des valeurs de retour, qui sont peuvent être affichées à l’écran. Nous avons déjà vu quelques fonctions, comme le main et printline, et nous détaillerons le mécanisme général des fonctions en section 1.9. Concentrons-nous un instant sur les opérateurs. Il s’agit ni plus ni moins d’opérateurs au sens mathématique, à quelques différences près. Un opérateur typique est l’addition ’+’, qui produit un nombre c à partir de deux nombres a et b, ce que l’on note : a + b → c. Les valeurs a et b sont appelées les opérandes, et c est appelé le résultat, ou la résultante. Notez bien que nous avons utilisé le signe → à la place du signe =, et c’est là toute la différence avec les mathématiques : Un programme opère une transformation des valeurs, là où les mathématiques expriment des faits comme des (in)égalités ou des équations. Par exemple, 5+4 → 9 se lit “l’addition entière de la valeur 5 de type int et de la valeur 4 de type int produit la valeur 9 de type int”, et signifie que lorsque PHP rencontre l’opération 5+4, il la remplace par la valeur résultante, soit 9. On dit que PHP effectue une réduction d’expression. La valeur résultante a elle aussi un type, qui est int dans le cas précédent. Types int et float Tout nombre ayant un point ’.’ est considéré comme un nombre à virgule flottante. Par exemple 5 est du type int, alors que 5. est du type float. Les opérateurs courants du type int et float sont les opérateurs arithmétiques habituels, comme l’addition +, la soustraction -, la multiplication * et la division /. Ces opérateurs produisent une valeur du type int ou float. L’opérateur modulo % (le reste de la division entière de x par y) produit toujours un résultat de type int, même si ses opérandes sont de type float, par exemple 7.3 % 4.2 produit la valeur entière 3. Il existe aussi des opérateurs de comparaison entre valeurs. Voici les plus courants : 4. D’après George Boole, qui inventa l’algèbre de Boole au XIXè siècle, permettant de faire des calculs à partir des seules valeurs true et false. 1.3. VALEURS ET TYPES Opérateur A === B A !== B A<B A>B A <= B A >= B 11 Signification vaut true ssi l’expression A a la même valeur calculée que B true ssi A est différent de B true ssi A est inférieur à B true ssi A est supérieur à B true ssi A est inférieur ou égal à B true ssi A est supérieur ou égal à B Notez bien que la comparaison d’égalité est l’opérateur === et non =, qui a une toute autre signification que nous verrons plus tard 5 . Ces opérateurs produisent une valeur de type bool, c’est-à-dire qu’ils disent si oui ou non la comparaison est vérifiée. Nous utiliserons ces opérateurs notamment dans la section 1.8. Par exemple, -1 > 5 produit la valeur false. Type string Les chaînes de caractères, du type string, sont simplement du texte écrit entre guillemets simples comme ’Ceci est une chaîne’. L’opérateur principal sur les chaînes de caractères est l’opérateur de concaténation ’.’ qui produit une nouvelle chaîne à partir de deux chaînes, en les juxtaposant. Par exemple ’bon’. ’jour’ produit la valeur ’bonjour’, ce que l’on note : ’bon’. ’jour’ → ’bonjour’ Il est possible de comparer deux chaînes de caractères avec les opérateurs === et !==, qui produisent là aussi une valeur de type bool. Remarque : Puisque les chaînes de caractères sont entourées de guillemets simples (qui sont en fait des apostrophes), ajouter une apostrophe au milieu de la chaîne risque de “casser” la chaîne. Par exemple, pour PHP ’Avec l’apostrophe c’est mieux’ est en fait la chaîne ’Avec l’, suivie de apostrophe c qui n’est pas une chaîne et ne veut rien dire du point de vue du langage, suivi de ’est mieux’ qui est à nouveau une chaîne de caractères. PHP ne traitera donc pas ceci comme une seule chaîne, et affichera une erreur. Comment faire alors ? Comme dans de nombreux langages de programmation, en PHP il faut faire précéder les apostrophes par des antislash \ (ou backslash, que l’on peut trouver sur le clavier avec la combinaison Alt-Gr et 8), ce qui donne la chaîne de caractères : 1 ’Avec l\’apostrophe c\’est mieux’ Ainsi, si on souhaite l’afficher avec un printline : 1 printline(’Avec l\’apostrophe c\’est mieux’); cela affiche bien à l’écran : 5. Il existe aussi un opérateur ==, similaire à ===, mais plus permissif. Bien que pratique, il peut être dangereux à utiliser si l’on ne connaît pas son comportement exact. C’est pourquoi nous préférons utiliser ===. 12 CHAPITRE 1. INTRODUCTION AU PHP Avec l’apostrophe c’est mieux Type bool Les valeurs booléennes true et false sont rarement utilisées telles quelles, car on les utilise généralement en tant que résultat d’une opération produisant une valeur booléenne. Par exemple, 5 < 7 produit la valeur booléenne true, alors que ’bonjour’=== ’bonjour!’ produit la valeur false. Les opérateurs sur les booléens (sur les valeurs true et false) sont appelés opérateurs logiques. Il s’agit principalement 6 des opérateurs ’et’ logique &&, ’ou’ logique || et ’non’ logique !. Leurs opérandes sont de type bool, ainsi que leur valeur produite. Opérateur A && B A || B !A Signification vaut true si à la fois A et B ont la valeur true vaut true si A ou B ou les deux ont la valeur true non(A) : vaut true si A est false et réciproquement Par exemple, true && false produit false (et vaut donc la valeur false), alors que produit true. true || false 1.3.2 La fonction infos_expr La fonction infos_expr permet d’afficher à l’écran des informations concernant le résultat d’une expression, d’une opération ou simplement d’une valeur. Par exemple l’instruction : 1 infos_expr(35); affiche : int(35) signifiant que la valeur est 35 et qu’elle est de type int. De même, 1 infos_expr( 2 > 6 ); affiche : bool(false) signifiant que le résultat de l’opération est de type bool, et que la valeur de ce résultat est false. Et infos_expr(’bon’. ’jour’); affiche : 6. Il existe des opérateurs and et or, mais ils ont un comportement légèrement différent des || et &&, et par précaution, il vaut mieux ne pas les utiliser. Pour plus d’information : http://php.net/ manual/fr/language.operators.logical.php 1.4. EXPRESSIONS ET RÉDUCTION D’EXPRESSIONS 13 string(7) "bonjour" où 7 est le nombre de caractères que contient la chaîne. 1.3.3 Conversions de types Certaines fonctions de PHP permettent de transformer des valeurs d’un type dans un autre type. Par exemple, pour transformer un int ou un float en string, on peut utiliser la fonction strval, ce qui donne : strval(4.2) → ’4.2’ Dans l’autre sens, on peut “extraire” un nombre à partir d’une chaîne de caractères, en utilisant intval ou floatval, par exemple : floatval(’4.2’) → 4.2 Remarque : L’opérateur de concaténation convertit automatiquement les nombres en chaînes de caractères, c’est-à-dire qu’il utilise strval de manière invisible, ce qui permet de simplifier l’écriture de : 1 printline(’Nombre : ’ . strval(10)); en : 1 printline(’Nombre : ’ . 10); 1.4 Expressions et réduction d’expressions Une expression est une composition d’opérations et d’opérandes, qui peut être réduite (transformée), possiblement plusieurs fois de suite, de sorte à n’obtenir plus qu’une unique valeur irréductible, la résultante finale. Par exemple, 5+4*8-2 est une expression, de même que ’bonjour’, qui elle est une expression irréductible. On peut donc aussi dire qu’une expression est soit une valeur, soit une opération sur des (sous-)expressions. Développons la manière dont PHP réduit l’expression 5+4*8-2. Tout d’abord, il commence par réduire la multiplication, car il sait que cette opération est prioritaire sur l’addition et la soustraction : 5+4*8-2 → 5+32-2. PHP effectue d’abord l’opération 4*8, récupère la valeur produite 32, et remplace cette opération par sa valeur. L’addition et la soustraction ayant la même priorité, PHP commence par la première : 5+32-2 → 37-2. Enfin il termine par la soustraction : 37-2 → 35. ce que produit donc la valeur finale 35, de type entier. En effectuant toutes ces réductions élémentaires, l’une après l’autre, par ordre de priorité, PHP peut calculer le résultat de toute expression, aussi complexe soit-elle. L’opérateur . de concaténation de chaînes peut lui-aussi être utilisé plusieurs fois dans une expression, par exemple : → → → ’bon’. ’jour’. ’le ’. ’monde’ ’bonjour’. ’le ’. ’monde’ ’bonjour le ’. ’monde’ ’bonjour le monde’ 14 CHAPITRE 1. INTRODUCTION AU PHP Voici un exemple un peu plus complexe. L’expression : floatval(strval(12). ’.’. strval(34))+ 5 est tout à fait valide, et sa réduction produit la valeur 17.34 de type float : floatval(strval(12). ’.’. strval(34))+ 5 → floatval(’12’. ’.’. strval(34))+ 5 → floatval(’12.’. strval(34))+ 5 → floatval(’12.’. ’34’)+ 5 → floatval(’12.34’)+ 5 → 12.34 + 5 → 17.34 D’ailleurs, l’instruction : 1 infos_expr(floatval(strval(12) . ’.’ . strval(34)) + 5); affiche bien : float(17.34) Remarque : Dans toute expression, la priorité peut être forcée en utilisant les parenthèses. Par exemple : (5+4)*8-2 → 9*8-2. Ainsi, pour éviter tout problème de priorité entre les opérateurs, c’est-à-dire quels opérateurs agissent en premier, ainsi que pour faciliter la lecture et la compréhension, il est conseillé d’entourer les expressions dont la signification n’est pas évidente avec des parenthèses. Remarque : Il est important de noter que tout n’est pas expressions en PHP. Par exemple, printline(5+4) n’est pas une expression (il s’agit cependant d’une instruction), car elle ne fait qu’afficher ce résultat à l’écran, et ne produit pas une valeur que l’on peut utiliser dans une expression plus grande. En effet, si c’était une expression, on aurait le droit d’écrire quelque chose comme 5*printline(5+4), mais ce n’est pas le cas. Remarque : Il est généralement possible de déterminer le type de retour d’une expression sans même effectuer le calcul. Par exemple, dans l’expression 5.3+4*8-2, on peut remplacer les valeurs par leur type : float + int * int - int, et l’on peut appliquer les réductions de la même manière, si l’on connaît le type de retour des opérateurs utilisés. Ici, la multiplication d’entiers produit un entier : float + int * int - int → float + int - int. Puis l’addition entre un flottant et un entier produit un flottant : float + int - int → float - int. Et enfin la soustraction entre un flottant et un entier produit aussi un flottant : float - int → float. Ainsi, le type résultant de l’expression 5.3+4*8-2 sera float. Note : Au final, le résultat d’une expression, pour qu’il soit utile à quelque chose, doit être utilisé dans une instruction (comme printline). Par exemple, l’instruction suivante, seule, est inutile : 1 $x+2*$y; 1.5. VARIABLES 15 car le résultat du calcul n’est utilisé d’aucune façon. C’est un calcul "dans le vide", au contraire de : 1 printline($x+2*$y); Nous verrons par la suite d’autres manières de réutiliser un résultat. 1.5 Variables Les variables sont des cases mémoires de l’ordinateur dans lesquelles on peut stocker des valeurs. Il est possible de lire le contenu d’une telle case ou de le modifier. La valeur que contient une variable peut changer au cours du temps (au cours des exécutions des instructions), et le comportement du programme dépendra de ces variables. En PHP, une variable est identifiée par le symbole $ suivi d’une suite de caractères représentant son nom, par exemple $couleur. Lorsqu’une variable est utilisée dans une expression, elle est automatiquement remplacée par sa valeur. Par exemple, supposons que la variable $un_nombre contienne la valeur 42. L’expression 10*$un_nombre+5+$un_nombre se réduit alors comme suit : 10*$un_nombre+5+$un_nombre 10*42+5+$un_nombre 420+5+$un_nombre 425+$un_nombre 425+42 467 même, si la variable $une_chaine contient la valeur ’bonjour ’, $une_chaine . ’le monde’ sera réduite en ’bonjour le monde’. → → → → → De l’expression Pour afficher la valeur que contient la variable, il suffit alors de faire : 1 $x = 42; 2 printline($x); Ici, il n’y a pas de guillemet autour de $x dans l’appel au printline, car PHP doit d’abord transformer la variable $x en son contenu, ce qui revient à transformer l’instruction en : 1 printline(42); Le type de la valeur que contient une variable définit l’ensemble des opérations que l’on peut effectuer sur la variable, et l’on dit aussi qu’il s’agit du type de la variable. 1.5.1 Affectation de valeur à une variable Une variable contient une valeur ; on peut donc soit utiliser cette valeur, soit la modifier. Pour modifier la valeur de la case mémoire d’une variable, on utilise une affectation avec le signe = (à ne pas confondre avec le signe ===, qui sert lui à comparer des valeurs). 16 CHAPITRE 1. INTRODUCTION AU PHP À la gauche du signe =, on place la variable dont on veut modifier la valeur. À la droite du signe =, on place la valeur : 1 $x = 42; La valeur de $x ne sera modifiée qu’une fois que le programme aura exécuté cette instruction. Attention ! Il ne s’agit pas du signe = mathématique, mais bien d’une instruction de modification d’état. Il serait plus correct de lire ← à la place du signe =, par exemple : 1 $x ← 42; ce qui signifierait "faire l’action de mettre la valeur 42 dans la case mémoire de la variable $x" ou plus simplement "$x reçoit la valeur 42". Cette opération s’effectue toujours de la droite vers la gauche, jamais dans l’autre sens. La modification de la variable prend effet au moment où PHP exécute l’instruction d’affectation. L’ordre des instructions est donc toujours primordial. Par exemple, dans le code : 1 2 3 4 5 6 7 8 $x = 42; printline($x); $x = 17; printline($x); $x = 23; printline($x); les instructions sont exécutées dans l’ordre donc l’ordinateur affiche successivement les valeurs 42, puis 17, puis 23. À la fin de l’exécution du programme, $x a donc la valeur 23. À la droite du signe =, on peut tout à fait mettre une expression composée plutôt qu’une simple valeur : 1 $nombre = 5*7-intval(’5’ . ’2’); Dans ce cas, PHP commence par réduire l’expression avant d’assigner la résultante à la variable. Ainsi, l’instruction : 1 $nombre = $nombre + 1; incrémente la variable $nombre de 1, c’est-à-dire que sa valeur est augmentée de 1. Exercice 1 Que fera le programme suivant ? 1.5. VARIABLES 1 2 3 4 5 6 7 8 9 10 11 12 17 <?php function main() { $i = 5; printline($i); $i = $i+1; printline($i); $i = $i+10; printline($i); } ?> 1.5.2 Autres opérateurs d’affectations L’opérateur = est suffisant pour tout type d’affectation, mais il existe d’autres opérateurs qui permettent d’écrire plus simplement certaines affectations courantes. Voici quelques-uns des plus utilisés : Opérateur Signification $x++ $x-$x += $x -= $s .= A A C $x $x $x $x $s = = = = = $x $x $x $x $s + 1 - 1 +A -A .C Par exemple : 1 $x = 5; 2 $x += 10; 3 printline($x); affichera 15, et : 1 $x = 5; 2 $x++; 3 printline($x); affichera 6. De même que l’opérateur . permet de concaténer deux chaînes de caractères, l’opérateur .= permet d’augmenter à droite le contenu de la variable avec une chaîne de caractères : 18 1 2 3 4 CHAPITRE 1. INTRODUCTION AU PHP $nom = ’Jean’; $nom .= ’-Sébastien’; $nom .= ’ Bach’; printline(’Votre nom : ’ . $nom); affichera : Votre nom : Jean-Sébastien Bach 1.5.3 Conventions et nom de variables Il est conseillé de n’utiliser que des caractères alphabétiques (pas de symbole particulier comme + ou @, etc.) dans les noms des variables. Les caractères accentués ne sont pas recommandés. Le symbole _ (sous la touche 8) peut cependant être utilisé pour séparer les mots lorsque la variable possède un nom composé : $vitesse_electron. Les chiffres peuvent apparaître, mais jamais en début de nom. Il est par ailleurs vivement conseillé d’utiliser des noms de variables explicites (par exemple $hauteur ou $couleur_yeux) plutôt que des noms abscons comme $toto ou $a. 1.6 Notion de bloc d’instructions Nous allons souvent avoir besoin de regrouper une suite donnée d’instructions. C’est ce que l’on appelle un bloc d’instructions, et il commence toujours par une accolade ouvrante { et finit toujours par une accolade fermante } : 1 2 { 3 4 5 6 7 } instruction1 instruction2 instruction3 ... Voici un exemple de bloc d’instructions : 1 2 { 3 4 5 6 7 } $taille = 79; printline(’la taille est ’ . $taille); $forme = ’rectangulaire’; printline(’la forme est’ . $forme); Notez le passage à la ligne après la première accolade ainsi qu’avant l’accolade fermante. Notez aussi que tout ce qui se trouve à l’intérieur du bloc d’instructions a été décalé vers la droite d’un nombre fixe d’espaces (4 semble une valeur convenable). Comme 1.7. STRUCTURES DE CONTRÔLE 19 nous le verrons par la suite, une fois que l’on a fermé le bloc d’instructions, on revient au même niveau que les accolades. Cela s’appelle l’indentation. On dit que les lignes ont été indentées, ou tabulées. L’indentation est très importante pour rendre un programme lisible par l’homme (généralement la machine n’en a pas besoin). Lire la section B pour plus de détails sur la nécessité de l’indentation. Les blocs d’instructions sont nécessaires aux structures de contrôle. 1.7 Structures de contrôle Les structures de contrôle sont des éléments de base des langages de programmation qui permettent de modifier le comportement du programme selon la valeur des variables. Normalement, les instructions sont exécutées les unes à la suite des autres, dans l’ordre. Les structures de contrôle (de l’ordre d’exécution des instructions) permettent de modifier cet ordre au moment de l’exécution du programme. Elles sont de trois sortes : — les conditions, — les fonctions, — les boucles. 1.8 La condition if La condition if permet d’exécuter une suite d’instructions uniquement dans le cas où un test donné est vérifié. Par exemple : 1 if($x > 5) { 2 printline(’x est supérieur à 5’); 3 } (Notez aussi la tabulation ajoutée à l’intérieur des accolades, pour avoir une indentation claire.) Ce qui se trouve entre les parenthèses qui suivent le if s’appelle le test de la condition. Un test est une expression dont le calcul doit arriver soit à la valeur true, soit à la valeur false. Tout ce qui se trouve dans les accolades suivant le if est appelé le corps du if, et sera traité uniquement si le test de la condition est vérifié, donc si le résultat de l’expression du test est true. Les instructions du bloc d’instructions suivant le if seront soient toutes exécutées, soit aucune. Pour effectuer le test du if, on utilise des opérateurs de comparaison (cf. section 1.3.1). Par exemple : 1 if($x === 5) { 2 printline(’x est égal à 5’); 3 } 20 CHAPITRE 1. INTRODUCTION AU PHP Ces opérateurs permettent aussi de comparer des expressions et non seulement des variables ou des valeurs simples : 1 if($x+3 === $y*$z) { 2 printline(’Ok’); 3 } Dans un telle expression, on peut combiner plusieurs comparaisons en une seule en utilisant des opérateurs logiques (cf. section 1.3.1). Par exemple : 1 if( ( $x > 100 && $x < 200 ) || ($x > 500) ) { 2 printline(’100 < x < 200 ou bien x > 500’); 3 } 1.8.1 Utilisation du else Il est possible d’exécuter des instructions dans le cas où le test du if a échoué (le test vaut false). Il faut pour cela utiliser le mot-clef else : 1 if($x > 5) { 2 printline(’x est supérieur à 5’); 3 } else { 4 printline(’x est inférieur ou égal à 5’); 5 } Notez que le else se trouve entre l’accolade fermante des instructions du cas où le test est true, et l’accolade ouvrante du cas false. 1.8.2 Imbrication des conditions Il est tout à fait possible d’imbriquer les conditions : 1.8. LA CONDITION IF 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 $max = 0; if($x > $y) { printline(’x est if($x > $z) { printline(’x $max = $x; } else { printline(’z $max = $z; } } else { printline(’y est if($y > $z) { printline(’y $max = $y; } else { printline(’z $max = $z; } } 21 supérieur à y’); est la plus grande valeur des trois’); est la plus grande valeur des trois’); supérieur à x’); est la plus grande valeur des trois’); est la plus grande valeur des trois’); mais en gardant à l’esprit que le test if($x > $z) (par exemple) ne se fera que si la condition du if($x > $y) est vérifiée. Lorsque beaucoup de if et de else s’enchaînent, il est préférable d’utiliser des else (ou elseif) successifs plutôt que de multiplier les imbrications de blocs d’instructions. C’est-à-dire, au lieu de : if 1 if($x < 0) { 2 printline(’x est négatif’); 3 } else { 4 if($x < 10) { 5 printline(’x est inférieur à 10’); 6 } else { 7 if($x < 100) { 8 printline(’x est inférieur à 100’); 9 } else { 10 printline(’x est supérieur ou égal à 100’); 11 } 12 } 13 } il est préférable d’écrire : 22 1 2 3 4 5 6 7 8 9 CHAPITRE 1. INTRODUCTION AU PHP if($x < 0) { printline(’x est négatif’); } else if($x < 10) { printline(’x est inférieur à 10’); } else if($x < 100) { printline(’x est inférieur à 100’); } else { printline(’x est supérieur ou égal à 100’); } La forme générale du if est donc la suivante : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 if( test ) { instruction instruction ... } else if( test ) { instruction instruction ... } else if( test ) { instruction instruction ... ... } else { instruction instruction ... } où les instructions peuvent contenir elles aussi des if. Chaque test est une expression qui, une fois réduite, doit avoir la valeur true ou false. 1.9. LES FONCTIONS 1.9 23 Les fonctions Les fonctions servent à se simplifier la vie, non seulement lors de l’écriture d’un programme, mais aussi lors de sa modification si l’on veut en changer le comportement. Elles sont un champ fondamental de quasiment tous les langages de programmation. 1.9.1 Un premier exemple Supposons que l’on veuille créer un programme affichant le résultat suivant : Salut Gérard, Ici à Helsinki il fait beau et chaud, À bientôt, Alfred. Salut Sophie, Ici à Helsinki il fait beau et chaud, À bientôt, Alfred. Salut Marion, Ici à Helsinki il fait beau et chaud, À bientôt, Alfred. Le premier programme qui vient à l’esprit est de simplement afficher ce que l’on souhaite, ligne par ligne : 1 function main() { 2 printline(’Salut Gérard,’); 3 printline(’Ici à Helsinki il fait beau et chaud,’); 4 printline(’À bientôt,’); 5 printline(’Alfred.’); 6 printline(’’); 7 printline(’Salut Sophie,’); 8 printline(’Ici à Helsinki il fait beau et chaud,’); 9 printline(’À bientôt,’); 10 printline(’Alfred.’); 11 printline(’’); 12 printline(’Salut Marion,’); 13 printline(’Ici à Helsinki il fait beau et chaud,’); 14 printline(’À bientôt,’); 15 printline(’Alfred.’); 16 printline(’’); 17 } Mais comment faire pour se simplifier la vie au maximum ? Il serait mieux de ne pas avoir à réécrire plusieurs fois la même chose. Pour cela, on utilise une fonction. Le programme précédent s’écrit alors : 24 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 CHAPITRE 1. INTRODUCTION AU PHP // Définition de la fonction : // $prenom : string function carte_postale($prenom) { printline(’Salut ’ . $prenom . ’,’); printline(’Ici à Helsinki il fait beau et chaud,’); printline(’À bientôt,’); printline(’Alfred.’); printline(’’); } // Programme principal : function main() { carte_postale(’Gérard’); carte_postale(’Sophie’); carte_postale(’Marion’); } L’exécution de ce programme par PHP va produire exactement le même affichage que plus haut. Décortiquons ce programme. Distinguons tout d’abord deux parties : la définition de la fonction carte_postale et le programme principal (défini par la fonction spéciale main). Commençons par la fonction carte_postale. Tout d’abord il y a l’entête de fonction, aussi nommée signature de fonction : 1 // $prenom : string 2 function carte_postale($prenom) (Notez que l’accolade ouvrante n’est pas incluse dans la signature.) La seconde ligne déclare (grâce au mot clef function) une fonction nommée carte_postale, qui prend en argument une chaîne de caractères. Cet argument est utilisé en interne à la fonction comme une variable, comme l’indique le dollar en début de nom, et s’appelle aussi une variable d’entrée. La première ligne est un simple commentaire, et pourrait donc être omis, mais il a son utilité : il indique que le prénom est censé être du type string, donc une chaîne de caractères, et permet de savoir comment utiliser la fonction. Ce qui se trouve dans les accolades s’appelle le corps de la fonction et définit ce qu’elle doit faire lorsqu’elle est appelée. Il est important de comprendre que la déclaration et la définition de fonction seules ne conduisent pas à l’exécution des instructions du corps de la fonction. En effet, ici PHP ne fait que lire la définition (l’entête plus le corps), et la stocke dans sa mémoire pour pouvoir l’utiliser par la suite, lors d’un appel à cette fonction. Passons maintenant au programme principal et la fonction main. Cette fonction est spéciale car elle est automatiquement appelée par PHP lorsqu’il lui est demandé d’exécuter le fichier contenant le programme. En dehors de cela, il s’agit d’une fonction comme les autres. On y voit trois appels successifs à la fonction carte_postale, avec les arguments ’Gérard’, puis ’Sophie’, puis ’Marion’. Ces arguments sont bien des chaînes 1.9. LES FONCTIONS 25 de caractères (notez les guillemets simples autour des prénoms), comme cela est requis par la fonction et indiqué dans le commentaire de l’entête de la fonction pour l’argument $prenom. Prenons le premier appel : carte_postale(’Gérard’). Lorsqu’il exécute cet appel de fonction, PHP fait temporairement prendre à la variable d’entrée $prenom la valeur ’Gérard’, puis le corps de la fonction est exécutée. Tout se passe alors (presque) comme si l’appel de fonction était remplacé automatiquement par le corps de la fonction, où la variable d’entrée prend la valeur qui lui est passée en argument. Pour ce premier appel, PHP “transforme” automatiquement ainsi le programme ci-dessus en ceci : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // Définition de la fonction : // $prenom : string function carte_postale($prenom) { printline(’Salut ’ . $prenom . ’,’); printline(’Ici à Helsinki il fait beau et chaud,’); printline(’À bientôt,’); printline(’Alfred.’); printline(’’); } // Programme principal : function main() { // PHP est en train d’effectuer l’appel à carte_postale(’Gérard’) ; // PHP remplace l’appel par le corps de la fonction appelée : { $prenom = ’Gérard’; printline(’Salut ’ . $prenom . ’,’); printline(’Ici à Helsinki il fait beau et chaud,’); printline(’À bientôt,’); printline(’Alfred.’); printline(’’); } // Suite du programme principal : carte_postale(’Sophie’); carte_postale(’Marion’); } Et cette fois les instructions de la fonction sont bien exécutées. Une fois l’appel de fonction effectué, et donc les instructions du corps de la fonction exécutées, PHP passera à la ligne suivante dans le programme initial, et tombera à nouveau sur un appel à la fonction carte_postale. Il fera donc comme pour le premier appel, et le développera en le corps de la fonction, mais cette fois avec un autre argument : 26 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 CHAPITRE 1. INTRODUCTION AU PHP // Définition de la fonction : // $prenom : string function carte_postale($prenom) { printline(’Salut ’ . $prenom . ’,’); printline(’Ici à Helsinki il fait beau et chaud,’); printline(’À bientôt,’); printline(’Alfred.’); printline(’’); } // Programme principal : function main() { // Cet appel a déjà été effectué : carte_postale(’Gérard’); // On passe maintenant au deuxième appel de fonction : // PHP remplace l’appel par le corps de la fonction appelée : { $prenom = ’Sophie’; printline(’Salut ’ . $prenom . ’,’); printline(’Ici à Helsinki il fait beau et chaud,’); printline(’À bientôt,’); printline(’Alfred.’); printline(’’); } // Suite du programme principal : carte_postale(’Marion’); } Et il en sera de même pour le dernier appel de fonction. 1.9.2 Variables locales En PHP (et, à nouveau, comme dans de nombreux langages), à l’intérieur d’une fonction, on ne peut pas utiliser des variables qui sont définies ailleurs que dans la fonction elle-même. Par exemple, le programme suivant ne fonctionne pas : 1 2 3 4 5 6 7 8 9 10 11 <?php // Définition de la fonction : function carte_postale() { printline(’Salut ’ . $prenom . ’,’); printline(’Ici à Helsinki il fait beau et chaud,’); printline(’À bientôt,’); printline(’Alfred.’); printline(’’); } // Programme principal : 1.9. LES FONCTIONS 27 12 function main() { 13 $prenom = ’Gérard’; 14 carte_postale(); 15 } 16 ?> Ici, la variable $prenom n’est pas partagée entre les deux fonctions, il s’agit donc de deux variables différentes (bien qu’elles aient le même nom). PHP affichera alors le message d’erreur suivant : 1 2 3 4 5 6 PHP Notice: Undefined variable: prenom on line 4 Salut ,<br /> Ici à Helsinki il fait beau et chaud,<br /> À bientôt,<br /> Alfred.<br /> <br /> Cette interdiction est intentionnelle, et permet principalement de “cloisonner” les fonctions. Les programmeurs utilisent couramment de nombreuses fonctions qui ont été créées par d’autres programmeurs. Supposons que le programmeur A soit en train d’écrire la fonction carte_postale qui utilise donc la variable $prenom. Dans cette fonction, il compte faire appel à une autre fonction afficher_photographie_carte_postale (qui, donc, affiche une photographie sur la carte postale, à côté du texte par exemple). Cette dernière fonction utilise aussi une variable $prenom mais pour un tout autre usage, par exemple pour afficher le prénom du photographe. Cette fonction a été programmée par une autre personne B. Voici ce à quoi ressemble la fonction du programmeur A : 1 // $prenom : string 2 function carte_postale($prenom) { 3 afficher_photographie_carte_postale(’cathedrale_Helsinki.jpeg’); 4 printline(’Salut ’ . $prenom . ’,’); 5 ... 6 } Si dans la fonction afficher_photographie_carte_postale la variable $prenom était effectivement la même que celle de la fonction carte_postale, sa valeur pourrait être modifiée, et la fonction carte_postale du programmeur A risquerait d’afficher le prénom du photographe à la place de celui souhaité. Le programmeur A devrait alors faire très attention aux noms de variable qu’il utilise, et s’assurer qu’aucune des fonctions appelées dans sa fonction n’utilise les mêmes variables. De plus, si un problème de ce type apparaissait, il serait impossible de s’en rendre compte en lisant simplement le code de la fonction carte_postale ; il faudrait aller vérifier dans les autres fonctions (ce qui serait très agaçant, car on utilise souvent de nombreuses fonctions). Heureusement, en PHP il n’en est pas ainsi, et le programmeur A n’a pas à se soucier des variables utilisées par les fonctions qu’il appelle et peut se contenter de savoir ce que fait une fonction sans avoir besoin de savoir comment elle le fait. Ainsi, même si les noms 28 CHAPITRE 1. INTRODUCTION AU PHP des variables sont les mêmes dans les deux fonctions, ce ne sont pas les mêmes variables. Sur le même principe et pour les mêmes raisons, il n’est pas possible d’avoir accès aux variables d’une fonction que l’on appelle, hormis évidemment pour le passage des arguments aux variables d’entrée. On dit alors que les variables (qu’elles soient ou non) d’une fonction sont des variables locales à la fonction. Une fonction n’a accès qu’à ses propres variables, et ses variables n’existent qu’à l’intérieur de cette fonction. Voici un autre exemple. Le programme suivant : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?php function une_fonction() { $x = 3; printline(’Dans une_fonction, après modif, valeur : ’ . $x); } // Programme principal : function main() { $x = 1; printline(’Au début, valeur : ’ . $x); une_fonction(); printline(’Après appel, valeur : ’ . $x); } ?> affichera : 1 Au début, valeur : 1<br /> 2 Dans une_fonction, après modif, valeur : 3<br /> 3 Après appel, valeur : 1<br /> ce qui montre bien que la variable $x présente dans la fonction une_fonction est une variable différente de la variable $x du programme principal. En fait, dans tout programme, on doit pouvoir renommer les variables dans une fonction sans que cela ait d’incidence sur le reste du programme. En effet, le programme ci-dessus est strictement équivalent au programme suivant : 1.9. LES FONCTIONS 1 2 3 4 5 6 7 8 9 10 11 12 29 function une_fonction() { $yyy = 3; printline(’Dans une_fonction, après modif, valeur : ’ . $yyy); } // Programme principal : function main() { $x = 1; printline(’Au début, valeur : ’ . $x); une_fonction(); printline(’Après appel, valeur : ’ . $x); } qui affichera donc la même chose. Les variables utilisées à l’intérieur d’une fonction n’ont donc aucun rapport avec les variables qui existent à l’extérieur ou dans une autre fonction. Plusieurs fonctions peuvent utiliser chacune une variable ayant le même nom, mais il faut néanmoins considérer qu’il s’agit de variables différentes. Si vous avez bien compris le principe des variables locales, vous devriez pouvoir répondre à la question suivante. Exercice 2 Pourquoi le programme ci-dessous : 1 2 3 4 5 6 7 8 9 10 11 12 <?php function une_fonction() { printline(’Dans une_fonction, valeur : ’ . $x); } // Programme principal : function main() { $x = 1; printline(’Au début, valeur : ’ . $x); une_fonction(); } ?> produit le message d’erreur suivant ? 1 Au début, valeur : 1<br /> 2 PHP Notice: Undefined variable: x on line 3 3 Dans une_fonction, valeur : <br /> 1.9.3 Arguments multiples Il est possible de passer plusieurs valeurs en argument d’une fonction et de son appel. Il faut pour cela séparer les arguments d’entrée par des virgules, que ce soient les variables de l’entête de fonction ou les valeurs passées en argument. Par exemple : 30 1 2 3 4 5 6 7 8 9 10 11 12 13 14 CHAPITRE 1. INTRODUCTION AU PHP // $larg : int // $long : int // -> int function aire($larg, $long) { return $larg*$long; } // Programme principal : function main() { $largeur = 10; $longueur = 23; $aire_du_rectangle = aire($largeur, $longueur); printline(’Aire du rectangle : ’ . $aire_du_rectangle); } Lors de l’appel de fonction, PHP utilise l’ordre des arguments pour assigner les valeurs passées aux variables d’entrée de la fonction. Remarque : Il n’y a pas de limite au nombre d’arguments que l’on peut utiliser, mais en pratique il est rare de dépasser 5 ou 6 arguments. 1.9.4 Valeur de retour Les fonctions permettent de décomposer un programme en plusieurs morceaux réutilisables. Pour le moment, celles que nous avons vues ne permettaient que d’afficher des chaînes de caractères à l’écran. Mais les fonctions ont une autre utilité : à l’instar des fonctions mathématiques et des opérateurs sur les expressions (cf. section 1.3.1 et 1.4), grâce au mot clef return, elles peuvent renvoyer une valeur à “celui” qui a appelé la fonction. C’est-à-dire qu’un appel de fonction est une expression, car il calcule une valeur qui peut être utilisée dans une expression plus grande. Pour reprendre le vocabulaire de la section 1.3.1, une fonction utilisant le return est donc comme un opérateur sur des valeurs, où les opérandes sont les arguments et la valeur de retour est la valeur produite par la réduction de l’appel de fonction. Prenons un exemple. Supposons que l’on veuille faire une fonction qui calcule le carré d’un nombre. On pourrait écrire : 1 // $x : int 2 function carre($x) { 3 printline($x*$x); 4 } Supposons maintenant que l’on souhaite écrire la fonction : 1 // $x : int 2 function puissance4($x) qui est donc censée élever un nombre à la puissance quatre. Il serait pratique de pouvoir réutiliser la fonction carre que nous venons d’écrire (pour 1.9. LES FONCTIONS 31 mieux cerner l’intérêt de la chose, supposons que la fonction carre soit bien compliquée, de sorte que l’on n’ait aucune envie de réécrire la même chose dans puissance4). On aimerait ainsi pouvoir écrire la fonction similairement à ceci : 1 // $x : int 2 function puissance4($x) { 3 $x_puiss4 = carre(carre($x)); 4 printline($x_puiss4); 5 } Mais ceci n’est pas possible avec la définition courante de la fonction carre, car on ne peut pas récupérer la valeur affichée à l’écran pour la réutiliser, et on ne peut pas non plus accéder, depuis puissance4, à une variable que l’on définirait dans carre et qui contiendrait le carré de $x, puisque les variables sont locales aux fonctions (voir section 1.9.2). La bonne manière de procéder est de faire en sorte que la fonction carre renvoie (ou retourne) la valeur qu’elle a calculée, plutôt que de l’afficher. Pour cela, on utilise le mot clef return, pour redéfinir la fonction carre : 1 2 3 4 5 // $x : int // -> int function carre($x) { return $x*$x; } Cette fonction ne fait aucun affichage, mais uniquement un calcul, c’est-à-dire qu’elle construit à la volée une valeur correspondant au carré calculé, et transmet cette valeur à celui qui a effectué l’appel de fonction. Ceci est indiqué par le commentaire // -> int, qui signifie que la fonction retourne une valeur de type entier, et donc que celui qui appellera cette fonction recevra en retour une valeur de type entier. Notez qu’il s’agit bien d’une valeur de retour, et non d’une variable. Ainsi, au contraire des arguments d’entrée, la valeur de retour n’a pas de nom (de variable) associé, cette valeur est donc anonyme dans la fonction. On peut alors y faire appel sans qu’aucun affichage ne soit effectué, par exemple : 1 $carre_de_5 = carre(5); Sur la droite de l’affectation, il y a une expression qui est un appel de fonction à carre qui prend en argument l’entier 5. Pour exécuter cette ligne d’instructions, PHP calcule d’abord la valeur de cette expression de droite, donc il commence par calculer la valeur de retour de l’appel de fonction, et remplace l’appel de fonction par la valeur de retour calculée, ce qui donne : 1 $carre_de_5 = 25; puis, finalement, modifie la valeur de la variable $carre_de_5 par la nouvelle valeur calculée, soit 25. On peut maintenant utiliser la nouvelle fonction carre et l’appeler dans la fonction 32 CHAPITRE 1. INTRODUCTION AU PHP puissance4. De cette manière, la fonction puissance4 ci-dessus fonctionnera comme prévu. Mais elle a elle-même l’inconvénient de ne pas pouvoir transmettre la valeur qu’elle calcule à celui qui l’appellera, et il faut donc la transformer à son tour pour utiliser le mot clef return. Voici le programme complet : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 // $x : int // -> int function carre($x) { return $x*$x; } // $x : int // -> int function puissance4($x) { $x_puiss4 = carre(carre($x)); return $x_puiss4; } // Programme principal : function main() { $puiss4_de_5 = puissance4(5); printline(’La puissance 4 de 5 est ’ . $puiss4_de_5); } Notez que l’affichage par le printline se trouve déplacé dans le programme principal. Ceci toujours dans l’objectif de pouvoir réutiliser ces deux fonctions sans pour autant afficher quoi que ce soit à l’écran, quelque soit le nombre de fois qu’on les utilise. Ainsi, l’instruction suivante : 1 printline(puissance4(3)+carre(12)*puissance4(carre(7)*5)); n’affichera que le résultat du calcul, et non toutes les valeurs intermédiaires retournées par les différents appels de fonction. Note : L’instruction return sera toujours la dernière instruction exécutée dans une fonction, c’est-à-dire que toute instruction placée après le return sera simplement ignorée par PHP. Remarquons cependant que le return peut apparaître parfois ailleurs qu’en toute fin de fonction, par exemple dans un if : 1 2 3 4 5 6 7 8 9 10 11 // $x : int // -> boolean function une_fonction($x) { if(x < 10) { return true; } else if (x > 20) { return true; } else { return false; } } 1.9. LES FONCTIONS 33 Quand doit-on utiliser return et quand doit-on utiliser un affichage ? Cela dépend de ce que l’on veut faire, mais il est très courant d’utiliser le return et de délocaliser les éventuels printline en dehors de la fonction, car un printline empêche toute réutilisation “silencieuse” de la fonction. Lors des TD, s’il vous est demandé d’écrire une fonction qui retourne ou renvoie une quelque chose, alors il vous faudra nécessairement utiliser le return. De plus, vous devrez respecter la signature des fonctions ; ainsi si les commentaires de la signature contiennent // -> XXX, cela signifie que la fonction doit utiliser le return, et que la valeur de retour doit avoir comme type XXX. Par exemple, la fonction carte_postale pourrait s’écrire : 1 2 3 4 5 6 7 8 9 10 // $prenom : string // -> string function carte_postale($prenom) { $carte = ’Salut ’ . $prenom . ’,’ . newline(); $carte .= ’Ici à Helsinki il fait beau et chaud,’ . newline(); $carte .= ’À bientôt,’ . newline(); $carte .= ’Alfred.’ . newline(); $carte .= newline(); return $carte; } ce qui permet de récupérer la chaîne de caractères correspondant à la carte postale, et de la transformer à nouveau avant de l’afficher, par exemple en la passant en argument à une autre fonction qui s’occuperait d’ajouter l’adresse du destinataire. Remarque : Il n’est possible de renvoyer qu’une unique valeur par le return, mais, bien que ceci soit assez rarement utile, cette limitation peut être levée en retournant un tableau de valeurs (voir section 1.13). 1.9.5 Valeur par défaut En PHP, certains arguments de fonction peuvent prendre une valeur par défaut si aucune valeur n’est fournie lors de l’appel de fonction. Cette valeur par défaut se place juste après la variable d’entrée concernée, précédée d’un signe ’=’ : Lors de l’appel de fonction, pour utiliser une valeur par défaut, il suffit d’omettre la valeur. Par exemple : 1 2 3 4 5 6 7 // $prenom : string function carte_postale($prenom = ’Charlie’) { printline(’Salut ’ . $prenom . ’,’); } carte_postale(); // équivalent à: carte_postale(’Charlie’); carte_postale(’Gérard’); Une fonction peut avoir plusieurs variables d’entrée avec une valeur par défaut. Les valeurs par défaut doivent nécessairement être placées à la fin de la liste d’arguments, après tous les autres arguments ne proposant pas de valeur par défaut. Par exemple : 34 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 CHAPITRE 1. INTRODUCTION AU PHP // $a : // $b : // $c : // $d : function ... } int string int string une_fonction($a, $b, $c = 5, $d = ’cookie’) { // Programme principal : function main() { // appels de fonctions valides : une_fonction(3, ’donut’, 10, ’cheesecake’); une_fonction(3, ’donut’, 10); une_fonction(3, ’donut’); // appels de fonctions non valides : une_fonction(3, ’donut’, ’cheesecake’); une_fonction(3); une_fonction(’donut’, 3); } 1.9.6 Forme générale d’une fonction Voici maintenant la forme générale d’une fonction : 1 2 3 4 5 6 7 8 // <var> : <type> // ... // -> <type-sortie> function <nom-de-la-fonction>(<var>, ... , <var> = <val>, ...) { <instruction> ... return <expr>;; } où <var> représente une variable, <val> une valeur, <expr> une expression, <XXX> ... signifie que l’on peut avoir 0, 1 ou plusieurs éléments similaires à <XXX>. Note : Certaines fonctions n’utilisent pas le mot clef return, auquel cas il n’est pas nécessaire de fournir dans les commentaires le type de sortie, qui est alors NULL. Note : L’indentation à l’intérieur d’une fonction respecte bien le principe général suivant : Tout ce qui se trouve entre deux accolades doit être décalé à droite d’un cran (une tabulation, ou 4 espaces) de plus que ce qui est en dehors des accolades. Voir l’annexe B page 118 pour plus d’informations. 1.9. LES FONCTIONS 1.9.7 35 Plusieurs fonctions Si l’on veut écrire plusieurs fonctions, il faut les écrire les unes en dessous des autres, avant le programme principal. Par exemple : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 // $x : int // $y : int // -> int function somme($x, $y) { return $x + $y; } // $x : int // $y : int // -> int function difference($x, $y) { return $x - $y; } // $x : int // $y : int // -> int function produit($x, $y) { return $x * $y; } // Programme principal : function main() { printline(’Somme de 4 et 5 : ’ . somme(4, 5)); printline(’Différence de 4 et 5 : ’ . difference(4, 5)); printline(’Produit de 4 et 5 : ’ . produit(4, 5)); } Les définitions de fonctions ne doivent pas être imbriquées les unes dans les autres, c’est-à-dire que le morceau de code suivant est à proscrire : 1 function ma_fonction1() { 2 ... 3 function ma_fonction2() { 4 ... 5 } 6 ... 7 } 1.9.8 Signatures simplifiées Il est possible d’écrire des signatures de fonctions simplifiées en omettant dans les commentaires les noms des variables, mais en respectant leur ordre. Par exemple : 36 1 2 3 4 CHAPITRE 1. INTRODUCTION AU PHP // $a : int // $b : string // -> boolean function une_fonction($a, $b) peut s’écrire : 1 // int string -> boolean 2 function une_fonction($a, $b) 1.9.9 Avantages de l’utilisation de fonctions Si les fonctions existent dans quasiment tous les langages de programmation, c’est parce qu’elles ont de nombreux avantages 7 . Elles permettent notamment : — d’éviter d’écrire plusieurs fois la même chose, — de faciliter la modification d’un programme : au lieu de modifier à plusieurs endroits, il suffit de modifier une seule fois dans la fonction, ce qui limite aussi le risque d’oublier une des modifications à effectuer, — de décomposer un programme en “sous-programmes”, ce qui permet en retour : — d’alléger le nombre de choses que le programmeur doit conserver en mémoire et prendre en compte à un instant donné : il lui suffit de savoir ce que la fonction prend en argument et retourne en sortie, sans avoir à se soucier de comment elle le fait, — de rendre le programme plus lisible en séparant visuellement les différentes fonctionnalités, — de réutiliser rapidement et facilement une fonction qui existe déjà, sans avoir à la reprogrammer (et faire des copier/coller qui sont fortement sujets aux erreurs. . .), — de fournir aux autres programmeurs des ensembles de fonctions utiles. Remarque : Grâce au mot clef include, il est même possible de mettre des fonctions dans des fichiers différents, et de les importer avec : 1 include(’le_fichier_contenant_les_fonctions.php’); C’est ce que l’on appelle la programmation modulaire. 7. Certains langages comme Lisp sont basés entièrement sur la notion de fonction : http://fr. wikipedia.org/wiki/Lisp . 1.10. LA BOUCLE WHILE 1.10 37 La boucle while "Comment afficher les nombres de 1 à 1000, sans les écrire tous un par un ?" Le principe des boucles est de répéter un même schéma un certain nombre de fois d’affilé jusqu’à une condition d’arrêt. Comme dans une recette de cuisine, "battre les oeufs en neige" signifie "faire plusieurs fois <battre les oeufs> jusqu’à <les oeufs sont montés en neige>", où ici le schéma répétitif est le fait de battre une seule fois les oeufs. Pour créer des boucles, il faut donc repérer le schéma répétitif et identifier la condition d’arrêt. En PHP, toute tâche répétitive peut se réaliser avec la boucle while. Le schéma général de la boucle while est le suivant : 1 while(condition) { 2 instruction 3 instruction 4 ... 5 } On remarque immédiatement la similarité avec la condition if, mais contrairement à ce dernier qui n’est pas une boucle, le while effectue plusieurs fois le groupe d’instructions, tant que la condition condition est vérifiée. En français, while signifie tant que, et il faut réellement le penser comme cela : 1 tant que(la condition est vérifiée) faire 2 des instructions Pour battre les oeufs en neige, il faut écrire : 1 tant que(les oeufs ne sont pas montés en neige) faire 2 battre les oeufs où la condition est mise cette fois sous forme négative : le "tant que" est la forme négative du "jusqu’à ce que". Réfléchissez donc bien à votre condition de boucle ; cela aide généralement de l’exprimer clairement en français. Voici en exemple la boucle permettant d’afficher les nombres de 1 à 20 : 1 2 3 4 5 6 7 8 $i = 1; while($i <= 20) { print($i . ’ ’); $i++; } printline(’Fin !’); Ce qui produit le résultat suivant : 38 CHAPITRE 1. INTRODUCTION AU PHP 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 Fin ! Juste avant la boucle, on commence par donner une valeur initiale à la variable $i. On arrive ensuite sur la boucle while. Avant même d’entrer pour la première fois dans la boucle pour exécuter les instructions répétitives, on commence par tester la condition. C’est pour cela qu’elle se trouve au dessus des instructions répétitives. Si la condition n’est pas vérifiée (sa valeur est false ), on sort immédiatement de la boucle, sans même avoir effectué une seule fois les instructions de boucle. Sortir de la boucle signifie passer aux instructions qui suivent l’instruction ou le bloc d’instructions de la boucle, en l’occurrence printline(’Fin !’);. Si par contre la condition est vérifiée (la valeur calculée est true), on entre dans la boucle pour exécuter les instructions répétitives, toujours selon leur ordre : on commence par afficher $i qui a la valeur 1, puis on incrémente $i, c’est-à-dire qu’on lui ajoute 1. Arrivé là, les instructions répétitives de la boucle sont finies pour le moment. Lorsque l’on a exécuté une fois les instructions de boucle, on remonte sur la condition et on la teste à nouveau. Idem, si elle n’est pas vérifiée, on sort de la boucle et on arrête d’exécuter les instructions de boucle. Sinon, si la condition est vérifiée, on exécute à nouveau les instructions de boucle, toujours dans le même ordre. Puis on remonte à nouveau sur la condition, que l’on teste à nouveau, et ainsi de suite jusqu’à ce que la condition ne soit plus vérifiée. Le programme exécute donc les lignes d’instructions dans cet ordre précis : 1, 3, 4, 5, 3, 4, 5, . . . 3, 4, 5, 8. Notez bien que la dernière instruction de la boucle while qui est exécutée est la condition, puisque c’est elle qui dit quand s’arrêter. Si jamais on met une mauvaise condition à la boucle, on risque soit de ne jamais entrer dans la boucle : 1 2 3 4 5 6 7 8 $i = 1; while($i < 0) { print($i . ’ ’); $i++; } printline(’la valeur de i est ’ . $i); ce qui affichera : la valeur de i est 1 soit de ne jamais sortir de la boucle : 1.11. LA BOUCLE DO...WHILE 1 2 3 4 5 6 7 8 39 $i = 1; while($i > 0) { print($i . ’ ’); $i++; } printline(’Ceci ne sera jamais affiché.’); ce qui écrira tous les nombres sans jamais arriver à la dernière ligne du programme. 1.10.1 Imbrications Dans un bloc d’instructions on peut mettre tout ce que l’on a vu jusqu’à maintenant : des affectations, des conditions, des affichages, des boucles, . . .Donc, tout comme pour le if, on peut imbriquer des boucles et des conditions if, ou des boucles et des boucles, etc. Exercice 3 Que fait alors le programme suivant ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <?php function main() { $x = 1; while($x <= 1000) { $n = 1; while($n <= 5) { print($x . ’ ’); $n++; } $x++; } } ?> Remarquez bien que l’instruction $n = 1; est placée à l’intérieur de la première boucle while, et sera donc exécutée pour chaque nouvelle valeur de $x. Si vous avez des difficultés à voir ce que fait ce programme, prenez un papier et un crayon et exécutez le programme à la main (au moins pour les premières valeurs) et notez à chaque instruction les valeurs de $x et $n. 1.11 La boucle do...while La boucle do...while fait exactement la même chose que la boucle while, à la seule différence que la condition est testée après les instructions répétitives : 40 CHAPITRE 1. INTRODUCTION AU PHP 1 do { 2 instruction 3 instruction 4 ... 5 } while(condition); Notez bien le ; à la fin du while. La boucle do...while garantit que l’on exécutera au moins une fois les instructions de boucle, ce qui peut être pratique dans certains cas pour éviter de réécrire les instructions au dessus de la boucle. Elle n’est cependant pas couramment utilisée. 1.12 La boucle for La boucle for n’est pas nécessaire en soi, puisque l’on pourrait toujours utiliser la boucle while, mais c’est une manière plus pratique et très courante d’écrire certains types de boucles. Elle est généralement utilisée lorsque l’on connaît à l’avance le nombre de fois où la boucle doit être exécutée. Sa forme générale est la suivante : 1 for(initialisation ; condition ; incrémentation) { 2 instruction 3 instruction 4 ... 5 } Notez bien des deux ; au milieu des parenthèses. Ce boucle est strictement équivalente à la forme suivante du while : 1 initialisation 2 3 while(condition) { 4 instruction 5 instruction 6 ... 7 incrémentation 8 } L’initialisation et la condition sont donc exécutées avant toute exécution des instructions répétitives. L’incrémentation (l’augmentation de la valeur de la variable de boucle), elle, est exécutée après, juste avant de tester à nouveau la condition. Par exemple, le code précédent : 1.12. LA BOUCLE FOR 1 2 3 4 5 6 7 8 41 $i = 1; while($i <= 1000) { print($i . ’ ’); $i++; } printline(’Fin !’); peut aussi s’écrire : 1 for($i = 1; $i <= 1000; $i++) { 2 print($i . ’ ’); 3 } 4 5 printline(’Fin !’); Avec un peu d’habitude, la boucle for est souvent plus lisibles que sa version while, car elle sépare nettement le "ce qu’il faut répéter" du "combien de fois il faut le répéter". Exercice 4 Transformer le programme de l’exercice 3 contenant les deux boucles while en un programme n’utilisant que des boucles for. 42 1.13 CHAPITRE 1. INTRODUCTION AU PHP Tableaux Les tableaux sont le dernier élément essentiel des langages de programmation. Un tableau est une suite de valeurs. Plus précisément, un tableau est une suite ordonnée de cases mémoires, chaque case mémoire pouvant contenir une valeur. Chaque case est associée à un indice qui permet de manipuler cette case comme une variable, soit pour utiliser sa valeur, soit pour la modifier. En PHP, comme dans de nombreux langages, l’indice de la première case d’un tableau est 0. Voici une schématisation d’un exemple de tableau, avec l’association entre l’indice et la valeur de chaque case : Indice : 0 1 2 3 4 5 6 7 8 9 Valeur : 1 64 95 3 17 77 2 95 83 4 Un tableau, tout comme une variable, peut bien sûr contenir autre chose que des valeurs numériques : Indice : 0 1 2 Valeur : ’rouge’ ’vert’ ’bleu’ En PHP, pour créer un tableau, on utilise le mot clef array. On peut alors créer un tableau vide comme suit : 1 // Création d’un tableau vide : 2 $tab = array(); On peut aussi l’initialiser avec des valeurs : 1 // Création et premier remplissage du tableau : 2 $nombres = array(1, 64, 95, 3, 17, 77, 2, 95, 83, 4); Après avoir exécuté cette dernière instruction, la variable $nombres contient le tableau ci-dessus. Les valeurs sont rangées dans l’ordre où elles sont données, et les indices sont mis automatiquement. Le tableau $nombres est aussi une variable, bien qu’il contienne plusieurs valeurs. Si plus tard on veut ajouter des valeurs à la fin d’un tableau, on peut utiliser la notation "[]" collée au nom du tableau à gauche de l’affectation : 1 2 3 4 5 6 7 8 // Création du tableau : $couleurs = array(’rouge’, ’vert’, ’bleu’); // Ajout de la valeur ’jaune’ en fin de tableau : $couleurs[] = ’jaune’; // Ajout de la valeur ’cyan’ en fin de tableau : $couleurs[] = ’cyan’; À la fin de ce programme, le tableau $couleurs contiendra donc les valeurs : Indice : 0 1 2 3 4 Valeur : ’rouge’ ’vert’ ’bleu’ ’jaune’ ’cyan’ Pour accéder à une case particulière d’un tableau, on utilise la même notation "[]" que précédemment, mais cette fois en spécifiant l’indice de la case souhaitée : 1.13. TABLEAUX 43 1 $couleurs2 = array(’rouge’, ’vert’, ’bleu’, ’jaune’, ’cyan’); 2 3 printline($couleurs2[2] . ’, ’ . $couleurs2[4]); Ce code affichera donc : bleu, cyan De la même manière, on peut modifier le contenu des cases : 1 $couleurs = array(’rouge’, ’vert’, ’bleu’); 2 3 $couleurs[0] = ’blanc’; 4 5 $couleurs[2] = ’noir’; À la fin de ce programme, le contenu du tableau $couleurs est : Indice : 0 1 2 Valeur : ’blanc’ ’vert’ ’noir’ 1.13.1 Parcours en boucle Pour parcourir chacune des cases d’un tableau (par exemple pour les afficher ou les modifier), on utilise une boucle. 1 2 3 4 5 6 7 $couleurs2 = array(’rouge’, ’vert’, ’bleu’, ’jaune’, ’cyan’); // Affichage de toutes les valeurs du tableau : for($indice = 0; $indice < count($couleurs2); $indice++) { $valeur = $couleurs2[$indice]; printline($valeur . ’, ’); } où count est une fonction qui retourne le nombre d’éléments que contient le tableau qui lui est passé en argument. La variable $indice va prendre successivement les valeurs 0, 1, 2. . .jusqu’à la taille du tableau - 1 (à cause du signe "<" qui fait arrêter la boucle dès que l’on a $indice === count($couleurs2)). Exercice 5 Écrire une boucle qui ajoute 1 à chaque valeur du tableau $nombres. 1.13.2 La boucle foreach La boucle foreach offre une manière plus pratique pour parcourir un tableau qu’une boucle for ou une boucle while. Voici un exemple d’utilisation, équivalent au dernier programme : 44 CHAPITRE 1. INTRODUCTION AU PHP 1 $couleurs2 = array(’rouge’, ’vert’, ’bleu’, ’jaune’, ’cyan’); 2 3 foreach($couleurs2 as $valeur) { 4 printline($valeur . ’, ’); 5 } Il signifie qu’on parcourt le tableau $couleurs avec la (nouvelle) variable $valeur qui prend successivement toutes les valeurs du tableau à chaque itération de la boucle. Il n’y a pas besoin de faire explicitement l’affectation suivante : 1 $valeur = $couleurs2[$indice]; car elle est faite implicitement par le foreach. Attention, supposons que l’on veuille mettre toutes les valeurs du tableau à ’blanc’ ; on ne peut pas faire, à l’intérieur de la boucle : 1 $valeur = ’blanc’; car on ne ferait que modifier la valeur de la variable $valeur sans toucher directement au contenu du tableau. Dans ce cas, on peut par contre utiliser une variable qui parcourt les indices du tableau (0, 1, 2. . .) avec la construction suivante du foreach : 1 $couleurs2 = array(’rouge’, ’vert’, ’bleu’, ’jaune’, ’cyan’); 2 3 foreach($couleurs2 as $indice => $valeur) { 4 printline(’indice : ’ . $indice); 5 // Affichage de l’ancienne valeur dans le tableau : 6 printline(’valeur : ’ . $valeur); 7 // Modification de cette valeur : 8 $couleurs2[$indice] = ’blanc’; 9 } 1.13.3 Tableaux associatifs Les précédents tableaux sont nommés tableaux scalaires, parce qu’ils utilisent des nombres pour les indices. Il existe une autre forme de tableaux, nommés tableaux associatifs, où les cases mémoires ne sont pas rangées par ordre croissant d’indice. On ne repère donc pas les indices des cases par leur numéro, mais par une clef qui est une chaîne de caractères. Voici un exemple : 1 2 3 4 5 6 7 $capitales = array(); // Ajout d’une nouvelle valeur et de sa clef associée : $capitales[’France’] = ’Paris’; // Idem : $capitales[’R.U.’] = ’Londres’; // Idem : $capitales[’Allemagne’] = ’Berlin’; 1.13. TABLEAUX 45 Ceci produira le tableau $capitales suivant : Indice : ’France’ ’R.U.’ ’Allemagne’ Valeur : ’Paris’ ’Londres’ ’Berlin’ Les clefs sont ici les pays, au même titre que les nombres étaient les indices pour les tableaux scalaires. Les valeurs sont les capitales. On peut écrire aussi directement les associations lors de la déclaration de la variable $capitales comme tableau : 1 $capitales = array( ’France’ => ’Paris’, 2 ’R.U.’ => ’Londres’, 3 ’Allemagne’ => ’Berlin’ ); Remarquez l’utilisation de la flèche =>, qui est exactement la même que pour le parcours dans le foreach avec indice et valeur. D’ailleurs, le parcours d’un tel tableau se fait logiquement avec la boucle foreach : p 1 $capitales = array( ’France’ => ’Paris’, 2 ’R.U.’ => ’Londres’, 3 ’Allemagne’ => ’Berlin’ ); 4 5 foreach($capitales as $clef => $valeur) { 6 printline(’Pays : ’ . $clef . ’ ; Capitale : ’ . $valeur); 7 } où cette fois les indices sont les clefs. Ceci affichera donc : Pays : France ; Capitale : Paris Pays : R.U. ; Capitale : Londres Pays : Allemagne ; Capitale : Berlin Pour les tableaux associatifs, il est plus courant d’utiliser la forme complète du foreach car on a plus souvent à la fois des valeurs et des clefs associées. Chapitre 2 Le paquetage AgroSIXPack 2.1 Introduction Le langage PHP a été initialement conçu pour la création de sites Web, interagissant pour cela avec le langage HTML (HyperText Markup Language) de description de pages Web. Dans ce cours, nous ne souhaitons pas entrer dans les détails du langage HTML, qui n’est que d’un intérêt pédagogique relatif. C’est pourquoi nous avons développé le paquetage AgroSIXPack (pour AgroParisTech Système d’Information eXtension Package), qui permet de masquer entièrement le langage HTML et de se concentrer sur la partie PHP. Sachez néanmoins que HTML existe et que le langage PHP que vous allez voir maintenant est une variante du PHP habituel (de base, pourrait-on dire). Il existe aussi des Systèmes de Gestion de Contenu (Content Management System, CMS) 1 permettant de créer des sites Web sans réelle notion de programmation 2 . Ces CMS sont très souvent basés sur un langage de programmation tel que Java ou PHP. Le paquetage AgroSIXPack peut être vu comme un petit CMS orienté programmation. Dans ce chapître, nous allons voir tout d’abord quelques fonctions supplémentaires d’affichage (section 2.3), puis nous aborderons la création et le traitement de formulaires (section 2.4). Enfin nous expliquerons le mécanisme des sessions (section 2.5) et très rapidement la création de styles CSS (section 2.6). 2.2 Installation et utilisation Pour installer AgroSIXPack sur votre ordinateur personnel, réferrez-vous à la section D.4, page 122. Remarque : Tout fichier .php exécuté par AgroSIXPack doit définir la fonction main. 1. http://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_contenu 2. Enfin, tant que l’on se cantonne aux fonctionnalités prévues, car la connaissance de la programmation (parfois avancée !) est très vite nécessaire dès que l’ont veut faire des sites un peu particuliers ou plus évolués. 46 2.3. AFFICHAGE 47 Cette fonction (et seulement celle-ci) est exécutée automatiquement par le paquetage au lancement de la page Web dans le navigateur. 2.3 Affichage Note : Ce chapitre contient de nombreuses signatures de fonction, ainsi que des arguments ayant des valeurs par défaut. Reportez-vous à la section 1.9 pour savoir comment les lire. La signature (parfois des groupes de signatures) est d’abord donnée, suivie d’un texte descriptif de la fonction. Attention : Dans tout ce qui suit, il très important de bien faire la distinction entre affichage d’une valeur à l’écran et renvoi d’une valeur par retour d’un appel de fonction. Seul le second cas permet de récupérer cette valeur pour la réutiliser dans un calcul ultérieur (une expression). L’affichage à l’écran ne sert réellement qu’à afficher des informations à l’utilisateur, pas plus, et ne permet pas de réutiliser la valeur calculée. Les fonctions qui retournent une valeur ont en commentaire // -> ... dans leur signature. 1 // $valeur : any 2 function print($valeur) Cette fonction est une des fonctions de base de PHP, elle permet simplement d’afficher une valeur à l’écran, que ce soit une chaîne de caractères ou un nombre, mais pas des tableaux. 1 // $texte : string 2 function printline($texte = ’’) Comme print mais passe à la ligne ensuite. 1 // -> string 2 function newline() Renvoie une chaîne de caractères correspondant à un passage à la ligne. Cette fonction doit donc être utilisée dans une fonction d’affichage telle que print pour que le passage à la ligne soit visible à l’écran. 1 // $texte : string 2 // $niveau : int 3 function afficher_titre($texte, $niveau = 1) Affiche une chaîne de caractères $texte avec un titre de niveau $niveau (de 1 à 6). 48 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK 1 function afficher_hrule() Affiche un ligne horizontale. 1 // $texte : string 2 // -> string 3 function bold($texte) 1 // $texte : string 2 // -> string 3 function emph($texte) Renvoient la chaîne de caractères $texte en gras ou en italique. Exemple : 1 printline(’En ’ . bold(’gras’) . ’ ou en ’ . emph(’italique’)); affichera : En gras ou en italique 1 // $classe : string 2 function debut_liste($classe = ’’) 1 // $texte : string 2 function afficher_liste_item($texte) 1 // $classe : string 2 function fin_liste($classe = ’’) Affichent une liste d’items. Les listes peuvent être imbriquées pour créer plusieurs niveaux, mais il doit toujours y avoir le même nombre d’appels à debut_liste et fin_liste . Exemple : 1 debut_liste(); 2 afficher_liste_item(’Banane’); 3 afficher_liste_item(’Kiwi’); 4 afficher_liste_item(’Mangue’); 5 fin_liste(); 1 // $classe : string 2 function debut_table($classe = ’’) 2.3. AFFICHAGE 49 1 // $classe : string 2 function fin_table($classe = ’’) Un appel à ces deux fonctions doit encadrer tout affichage de table. Les tables ne peuvent pas être imbriquées. 1 // $ligne : array(string) 2 function afficher_table_ligne($ligne) Affiche une ligne entière de données, à partir du tableau $ligne. Exemple : 1 debut_table(); 2 afficher_table_ligne(array(1,2,3)); 3 afficher_table_ligne(array(4,5,6)); 4 fin_table(); 1 // $ligne : array(string) 2 function afficher_table_entete($ligne) Comme afficher_table_ligne mais pour les entêtes des colonnes de la table. Cette fonction ne peut-être appelée qu’une seule fois par table, et avant toute autre ligne. 1 function debut_table_ligne() 1 // $data : string 2 function afficher_table_donnee($data) 1 function fin_table_ligne() Comme afficher_table_ligne mais décomposé en 3 fonctions. La fonction afficher_table_donnee doit être appelée autant de fois qu’il y a de cellules dans un ligne. Un ensemble d’appels doit être encadré des appels à debut_table_ligne et fin_table_ligne. Exemple : 50 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK 1 debut_table(); 2 debut_table_ligne(); 3 afficher_table_donnee(1); 4 afficher_table_donnee(2); 5 afficher_table_donnee(3); 6 fin_table_ligne(); 7 debut_table_ligne(); 8 afficher_table_donnee(4); 9 afficher_table_donnee(5); 10 afficher_table_donnee(6); 11 fin_table_ligne(); 12 fin_table(); 1 // $url : string 2 // $texte_alt : string 3 function afficher_image($url, $texte_alt = ’’) Affiche une image. L’$url doit être soit une adresse internet commençant par "http ://", soit un fichier local dont l’adresse est relative au dossier courant. Le texte $texte_alt est le texte affiché lorsque la souris est posée sur l’image. 1 2 3 4 // $texte : string // $page : string // $params : array(string=>string) function afficher_lien_interne($texte, $page, $params = array()) Affiche un lien interne vers une $page PHP (un fichier .php) relativement au répertoire courant. L’argument optionel $params est le tableau associatif des associations "var=val" de l’URL. Exemple : 1 afficher_lien_interne(’Retour vers l\’accueil’, ’accueil.php’); 1 // $texte : string 2 // $url : string 3 function afficher_lien_externe($texte, $url) Affiche un lien vers une URL externe (commençant par "http ://" ou "https ://"). Exemple : 1 afficher_lien_externe(’Aller sur Google’, ’http://www.google.fr’); 2.4. FORMULAIRES : INTERACTION AVEC L’UTILISATEUR 1 2 3 4 5 6 // $str : string // $page : string // $params : false/array(string=>string) // $args : array(string=>string) // -> string function lien_interne($str, $page, $params = false, $args = array()) 1 2 3 4 5 6 // $str : string // $url : string // $params : false/array(string=>string) // $args : array(string=>string) // -> string function lien_externe($str, $url, $params = false, $args = array()) 51 Comme afficher_lien_interne et afficher_lien_externe mais retournent la chaîne de caractères correspondant au lien au lieu de l’afficher directement. L’argument optionel $args est le tableau associatif des arguments de la balise HTML "a href". 2.4 Formulaires : Interaction avec l’utilisateur Jusque là, tout ce que nous avons vu en PHP ne peut nous servir qu’à faire du calcul ou à les afficher à l’écran. Nous allons maintenant voir comment interagir avec l’utilisateur, en lui demandant des valeurs, qui vont donc permettre de faire des calculs différents selon les valeurs récupérées. Pour cela, nous utilisons des formulaires. Il s’agit d’un ensemble d’outils permettant à l’utilisateur de saisir des valeurs ou de faire des choix, que l’on pourra prendre en compte dans les calculs subséquents. L’interaction via des formulaires se passe en trois temps : 1. Un formulaire (une page php) est affiché et présenté à l’utilisateur, 2. L’utilisateur remplit le formulaire et clique sur "Valider" (ou "Ok" ou "Envoyer", etc.), 3. Une autre page PHP reçoit les données envoyées par l’utilisateur et traite ces données. Il faut donc créer 2 fichiers PHP : l’un affichant le formulaire et l’autre traitant les données reçues. 2.4.1 Création et affichage de formulaires Intéressons-nous d’abord à la création et l’affichage de formulaires. Nous verrons par la suite comment récupérer les valeurs saisies par l’utilisateur dans les champs du formulaire. Un formulaire doit obligatoirement commencer par un appel à la fonction : 52 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK 1 // $id_formulaire : string 2 // $page : string 3 function debut_formulaire($id_formulaire, $page) où $id_formulaire est un nom interne (c’est-à-dire invisible par l’utilisateur) du formulaire, et $page est le nom de la page PHP (le fichier .php) qui recevra les données du formulaire lorsque l’utilisateur aura cliqué sur le boutont ’OK’. Un formulaire doit également obligatoirement finir par un appel à la fonction : 1 // $bouton_ok_str : string 2 function fin_formulaire($bouton_ok_str = ’OK’) qui ajoute un bouton permettant d’envoyer les données à la page $page qui sera alors exécutée. L’argument $bouton_ok_str est la chaîne de caractères affichée sur le bouton d’envoi des données. Ces deux appels doivent encadrer tous les champs (champ texte, case à cocher, etc., voir ci-dessous) de ce formulaire, sans quoi les données saisies par l’utilisateur pour ces champs ne seront pas envoyées à la page PHP censée traiter ces données. Voici un formulaire vide, avec uniquement le bouton de validation : 1 debut_formulaire(’nom_du_formulaire’, ’page_traitement.php’); 2 // ... insérer les champs de formulaire ici 3 fin_formulaire(’Envoyer !’); Et voici le résultat, si aucun champ de formulaire n’a été ajouté : Si l’utilisateur clique sur ce bouton, il sera redirigé vers la page page_traitement.php qui sera donc exécutée. Note : À la fin de cette section est donné un exemple complet de formulaire utilisant la plupart des fonctions présentées ci-après. Champs de formulaires Un formulaire contient différents champs, permettant à l’utilisateur de saisir des données et de faire des choix. Toutes les fonctions présentées ici servent à afficher des champs de formulaires. Il est important de comprendre que la valeur saisie par l’utilisateur dans un champ n’est pas accessible juste après l’appel à la fonction affichant ce champ, mais ne sera accessible que plus tard, dans un fichier de traitement séparé. Tout champ possède un identifiant $id_champ qui permet, lors du traitement des données saisies par l’utilisateur, de récupérer la valeur saisie dans le champ du nom donné (voir valeur_champ, section 2.4.2). 2.4. FORMULAIRES : INTERACTION AVEC L’UTILISATEUR 53 Voici maintenant l’ensemble des fonctions permettant d’afficher des champs de formulaires. 1 2 3 4 // $id_champ : string // $texte : string // $valeur : string function afficher_champ_texte($id_champ, $texte, $valeur = ’’) Ajoute au formulaire un champ de saisie de texte d’identifiant $id_champ, précédé par la chaîne de caractères $texte. L’argument $valeur permet de donner une valeur par défaut qui sera affichée dans le champ de saisie. 1 2 3 4 5 6 7 // $id_champ : string // $texte : string // $valeur : string // $rows : int // $cols : int // $classe : string function afficher_champ_paragraphe($id_champ, $texte, $valeur = ’’, $rows = 4, $cols = 20, $classe = ’’) Comme afficher_champ_texte, mais permet de saisir plusieurs lignes de texte. Les arguments $rows et $cols permettent de modifier le nombre de lignes et de colonnes de la boîte de saisie. (L’argument $classe est la classe CSS ; voir la section 2.6.) 1 2 3 4 // $id_champ : string // $texte : string // $valeur : string function afficher_champ_password($id_champ, $texte, $valeur = ’’) Comme afficher_champ_texte mais affiche des ’*’ à la place des caractères saisis au clavier. 1 2 3 4 // $id_champ : string // $texte : string // $checked : bool function afficher_checkbox($id_champ, $texte, $checked = false) Ajoute au formulaire une case à cocher seule, précédée du texte $texte. L’argument $checked définit si la case est cochée par défaut. 54 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK 1 // $id_champ : string 2 // $texte : string 3 function debut_groupe_checkbox($id_champ, $texte) 1 2 3 4 // $texte : string // $valeur : string/false // $checked : bool function afficher_checkbox_item($texte, $valeur = false, $checked = false) 1 function fin_groupe_checkbox() Ajoutent un groupe de cases à cocher au formulaire. Le groupe doit commencer par debut_groupe_checkbox, suivi de plusieurs appels à afficher_checkbox_item, et terminer par debut_groupe_checkbox Chaque appel à afficher_checkbox_item ajoute une case à cocher au groupe. L’argument $checked est le même que pour afficher_checkbox. Si l’argument $valeur est false, il prend la même valeur que l’argument $texte. Attention cependant, il faut éviter au maximum d’utiliser des espaces, des accents et des caractères spéciaux pour l’argument $valeur. Dans la mesure du possible, utilisez uniquement les lettres sans accent, les nombres et les caractères parmi "_+-*. :". Il est donc important de spécifier l’argument $valeur si l’argument $texte contient un des caractères à éviter. Voici un exemple d’utilisation et le résultat visuel correspondant : 1 debut_groupe_checkbox(’animaux’, ’Quels animaux avez-vous ?’); 2 afficher_checkbox_item(’Chat’, ’chat’); 3 afficher_checkbox_item(’Chien’, ’chien’); 4 afficher_checkbox_item(’Lapin’, ’lapin’); 5 fin_groupe_checkbox(); Pour savoir comment les valeurs peuvent être récupérées, voir 2.4.2. 1 // $id_champ : string 2 // $texte : string 3 function debut_groupe_radio($id_champ, $texte) 2.4. FORMULAIRES : INTERACTION AVEC L’UTILISATEUR 1 2 3 4 55 // $texte : string // $valeur : string/false // $checked : bool function afficher_radio_item($texte, $valeur = false, $checked = false) 1 function fin_groupe_radio() Comme pour groupe_checkbox, mais avec des boutons radios. Un seul bouton peut être sélectionné dans tout le groupe. 1 2 3 4 // $id_champ : string // $texte : string // $valeur : string/false function debut_select($id_champ, $texte, $valeur = false) 1 2 3 4 // $texte : string // $valeur : string/false // $selected : bool function afficher_select_item($texte, $valeur = false, $selected = false) 1 function fin_select() Comme pour groupe_checkbox, mais sous forme de liste déroulante. Un seul item peut être sélectionné dans tout le groupe. L’argument $selected correspond à $checked dans afficher_checkbox_item. 1 // $id_champ : string 2 // $valeur : string 3 function ajouter_champ_cache($id_champ, $valeur) Ajoute un champ caché au formulaire. Cela permet d’envoyer des données à travers le formulaire en même temps que les autres valeurs saisies par l’utilisateur, sans rien afficher. 56 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK Voici un exemple général de formulaire, montrant l’utilisation de la plupart des fonctions ci-dessus : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 <?php function afficher_formulaire() { debut_formulaire(’form1’, ’traitement2.php’); afficher_champ_texte(’prenom’, ’Prenom : ’, ’John’); afficher_champ_texte(’nom’, ’Nom : ’, ’Arbuckle’); afficher_champ_paragraphe(’para’, ’Texte : ’, "Bonjour\net bienvenue", 4, 23); debut_select(’liste’, ’Choix : ’); // valeur envoyée si choisi : premier afficher_select_item(’premier’); // valeur envoyée si choisi : 2 afficher_select_item(’second’, 2); fin_select(); debut_groupe_checkbox(’animaux’, ’Quels animaux avez-vous ?’); afficher_checkbox_item(’Chat’); afficher_checkbox_item(’Chien’, ’chien’, true); afficher_checkbox_item(’Lapin’, false, true); fin_groupe_checkbox(); // Une checkbox toute seule afficher_checkbox(’dors’, ’Je dors beaucoup’, true); debut_groupe_radio(’maradio’, ’Quel groupe préférez-vous ?’); afficher_radio_item(’Eiffel’); afficher_radio_item(’The Beatles’, ’beatles’, true); afficher_radio_item(’Noir Désir’, ’noirdez’); fin_groupe_radio(); fin_formulaire(’Envoyer’); } function main() { afficher_formulaire(); } ?> 2.4. FORMULAIRES : INTERACTION AVEC L’UTILISATEUR Et voici le résultat visuel correspondant : 57 58 2.4.2 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK Traitement des données de formulaire Voyons maintenant comment récupérer et traiter les données d’un formulaire qui a été rempli par l’utilisateur. Récupération et traitement des données saisies Pour récupérer une donnée saisie par l’utilisateur dans un des champs du formulaire, il faut utiliser la fonction : 1 2 3 4 // $id_champ : string // $default : any // -> string function valeur_champ($id_champ, $default = false) qui renvoie la valeur saisie dans le champ de nom $nom. Cette valeur est soit false, soit une chaîne de caractères 3 . L’argument $default est la valeur que retourne valeur_champ si le champ $id_champ n’existe pas. Voici le contenu du fichier "formulaire.php", qui affiche le formulaire à l’écran : 1 <?php 2 3 function afficher_formulaire() { 4 debut_formulaire(’form_sport’, ’traitement.php’); 5 afficher_champ_texte(’sport’, ’Sport favori :’); 6 afficher_champ_texte(’heures’, ’Nombre d\’heures de pratique par semaine :’); 7 fin_formulaire(); 8 } 9 10 function main() { 11 afficher_formulaire(); 12 } 13 14 ?> Lorsque PHP exécute ce fichier, il affiche le formulaire suivant : 3. Notez qu’en PHP, les valeurs 0, ” et false sont équivalentes vis-à-vis de l’opérateur == ; et qu’une chaîne de caractère non-vide est équivalente à true pour les tests, par exemple dans les if et while. C’est pourquoi il est préférable d’utiliser l’opérateur === à la place, qui considère 0, ” et false comme des valeurs différentes. 2.4. FORMULAIRES : INTERACTION AVEC L’UTILISATEUR 59 L’utilisateur peut alors saisir des informations dans les champs du formulaire. À ce stade, le fichier est fini d’être exécuté ; il ne peut donc pas savoir quelles données l’utilisateur est en train de saisir, et encore moins les utiliser. Lorsque l’utilisateur clique enfin sur "Envoyer", cela déclenche l’exécution par PHP du fichier "traitement.php". C’est ce fichier qui récupère les données de saisies par l’utilisateur pour les traiter. Ce fichier contient le code suivant : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <?php function traiter_formulaire() { // Récupération des données saisies dans le formulaire $sport = valeur_champ(’sport’); $heures = valeur_champ(’heures’); // Utilisation des données printline(’Votre sport est ’ . $sport . ’ que vous pratiquez ’ . $heures . ’ heures par semaine’); } function main() { // Récupération du nom du formulaire $id_formulaire = get_id_formulaire(); if($id_formulaire === ’form_sport’) { // Si on est arrivé sur cette page à cause d’une pression // sur le bouton Ok du formulaire ’form_sport’ traiter_formulaire(); } else { // Sinon on est arrivé ici par un autre formulaire // ou sans formulaire du tout printline(’Vous n\’êtes pas passés par le formulaire !’); } } ?> La fonction traiter_formulaire permet de récuperer les valeurs saisies par l’utilisateur. La fonction main vérifie d’abord que ce fichier .php a bien été exécuté juste que l’utilisateur a rempli et validé le bon formulaire ’form_sport’, et appelle la fonction traiter_formulaire le cas échéant, ou affiche un message sinon. Ceci est possible grâce à get_id_formulaire() qui retourne le nom du formulaire qui a été validé par l’utilisateur, ou qui retourne false si on est arrivé sur ce fichier .php sans passer par un formulaire (ceci peut arriver si on entre l’adresse du fichier directement). Notez aussi que l’appel à debut_formulaire dans "formulaire.php" a comme argument "traitement.php" : c’est ce qui permet de faire en sorte que lorsque l’utilisateur valide le formulaire, ce soit la page "traitement.php" qui soit exécutée. 60 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK Ainsi, supposons que l’utilisateur ait saisi ’Rugby’ pour le champ ’sport’, dans le fichier "formulaire.php" : 1 afficher_champ_texte(’sport’, ’Sport favori :’); Une fois le formulaire validé, on peut alors récupérer, dans "traitement.php", la valeur saisie par : 1 $sport = valeur_champ(’sport’); et $sport vaudra alors la valeur ’Rugby’. Récupération des données d’une seule checkbox Il est possible d’utiliser la fonction valeur_champ sur les checkbox, mais celle-ci renvoie le texte de la checkbox. Il est donc préférable d’utiliser la fonction : 1 // $id_champ : string 2 // -> bool 3 function valeur_checkbox($id_champ) qui renvoie true si la checkbox $nom a été cochée, false sinon. Récupération des données d’un groupe checkbox Pour récupérer les données d’un groupe checkbox, il faut par contre bien utiliser ce qui renvoie un tableau associatif où chaque clef est une des cases cochées par l’utilisateur. Il n’y a donc pas de clef pour les cases non-cochées. Pour reprendre l’exemple de la page 54 : valeur_champ, 1 $animaux_choisis = valeur_champ(’animaux’, array()); Notez que la valeur par défaut de valeur_champ est fixée à array(), qui est un tableau vide pour le cas où aucune checkbox du groupe n’aurait été cochée. Pour savoir si une clef existe dans le tableau, on peut utiliser la fonction array_key_exists (voir section A.1.7). Par exemple : 1 $animaux_choisis = valeur_champ(’animaux’, array()); 2 if(array_key_exists(’lapin’, $animaux_choisis)) { 3 printline(’Vous avez un lapin.’); 4 } Pour parcourir l’ensembles des valeurs cochées, on peut utiliser une boucle foreach. Exemple : 1 $animaux_choisis = valeur_champ(’animaux’, array()); 2 foreach($animaux_choisis as $nom_animal) { 3 printline(’Vous avez un ’ . $nom_animal); 4 } 2.4. FORMULAIRES : INTERACTION AVEC L’UTILISATEUR 61 Auto-validation de formulaire Il est tout à fait possible de faire traiter le formulaire par la page même qui a envoyé les données. On appelle cela un formulaire auto-validé. Dans ce cas, il faut bien avoir à l’esprit que les données ne seront traitées qu’à la seconde exécution du fichier, car à la première exécution, on ne peut qu’afficher le formulaire en attendant que l’utilisateur saisisse des données et clique sur "Envoyer", ce qui entraînera la seconde exécution du formulaire, mais cette fois avec des données à traiter récupérables par valeur_champ. Lors de la première exécution du fichier, get_id_formulaire() retourne généralement false 4 , et comme les champs de formulaire n’ont pas été validés, ils n’existent pas encore et valeur_champ() retourne alors la valeur par défaut spécifiée. Voici un exemple simple : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 <?php function afficher_formulaire() { debut_formulaire(’auto-formulaire’, ’auto-form.php’); afficher_champ_texte(’prenom’, ’Votre prénom :’); fin_formulaire(); } function traiter_formulaire() { $prenom = valeur_champ(’prenom’); printline(’Votre prénom : ’ . $prenom); } function main() { $id_formulaire = get_id_formulaire(); // On vérifie que l’on a bien recu des données du formulaire if($id_formulaire === ’auto-formulaire’) { // Ici, c’est forcément au moins la DEUXIÈME exécution du // fichier, car la première était nécessairement l’affichage // du formulaire alors que l’on n’avait encore aucune donnée // à traiter. traiter_formulaire(); } // On décide ici d’afficher le formulaire en dessous des données // traitées mais on pourrait le mettre au dessus. // On choisit d’afficher le formulaire est affiché à toutes les // exécutions du fichier, même si on traite des données. afficher_formulaire(); // Attention, l’affichage du formulaire NE bloque PAS l’exécution // du fichier en attendant que l’utilisateur entre des valeurs // dans le formulaire, i.e., la ligne suivante est affichée AVANT // que l’utilisateur n’entre des valeurs dans les champs et // ne clique sur OK: 4. Sauf si l’on vient d’un autre formulaire. 62 36 37 38 39 40 41 42 } 43 ?> CHAPITRE 2. LE PAQUETAGE AGROSIXPACK printline(’Fin d\’exécution du fichier.’); // On a fini, et c’est seulement maintenant que l’utilisateur // peut entrer des valeurs dans le formulaire, pas avant. // Lorsqu’il cliquera sur OK, cela appelera ce même fichier une // seconde fois, et entraînera donc son exécution, mais cette fois // avec les données saisies dans le formulaire par l’utilisateur. Dans l’exemple ci-dessus, on pourrait aussi n’afficher le formulaire que si l’on n’a pas reçu de données (et donc le masquer lors de la seconde exécution du fichier), ou si les données reçues sont invalides. Redirection de page Si l’on souhaite rediriger l’utilisateur vers une autre page PHP, on peut utiliser la fonction : 1 // $page : string 2 // $params : false/array(string=>string) 3 function redirection($page, $params = false) où $page est le nom du fichier PHP relativement au répertoire courant. Attention, aucun affichage ne doit avoir été fait au moment où cette fonction est exécutée. 2.5 Sessions Lorsque PHP passe d’une page à l’autre, il ne mémorise pas les valeurs des variables, il repart toujours de zéro. Pour pouvoir conserver des données d’une page à l’autre, on peut utiliser des champs cachés dans des formulaires, mais cela devient rapidement peu pratique quand le nombre de valeurs à mémoriser augmente. Le mécanisme adapté pour ce type de mémorisation est celui des sessions. La session est simplement un tableau associatif $_SESSION[], où l’on peut associer des clefs à des valeurs à mémoriser. Par exemple, pour mémoriser la valeur 12 pour la clef ’age’, il suffit de faire : 1 $_SESSION[’age’] = 12; Pour savoir si une clef existe dans la session, on peut utiliser array_key_exists. Voici le programme "compteur.php" qui permet de compter le nombre de fois où la page a été exécutée : 1 <?php 2 3 function main() { 4 2.6. MODIFICATION DU STYLE 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 } 31 32 ?> 63 // Si la clef ’compteur’ existe déjà dans la mémoire // de la session if(array_key_exists(’compteur’, $_SESSION)) { // alors récupérer sa valeur dans la variable $compteur $compteur = $_SESSION[’compteur’]; } else { // La clef ’compteur’ n’existe pas dans la session // On donne donc une valeur initiale $compteur = 0; } // Augmenter la valeur du compteur $compteur++; // Affichage printline(’Nombre d\’exécutions de la page : ’. $compteur); // Si on clique sur le lien suivant, cela exécute à nouveau la page // et incrémente donc le compteur afficher_lien_interne(’Recharger la page’, ’compteur.php’); // Mémoriser la nouvelle valeur du compteur // pour l’exécution suivante. // Si ce n’est la première fois que la page est exécutée, // cela remplace l’ancienne valeur $_SESSION[’compteur’] = $compteur; Pour détruire toutes les variables de sessions, on peut utiliser : 1 session_unset(); Pour détruire une variable de session en particulier, on peut utiliser : 1 unset($_SESSION[’ma_variable’]); 2.6 Modification du style L’affichage de base d’AgroSIXPack peut être modifié en y ajoutant des feuilles de style CSS (Cascading Style Sheet). Note : Les outils fournis dans cette section sont présentés pour information uniquement, pour pouvoir modifier l’apparence de l’affichage, mais ce ne sont pas des objectifs pédagogiques. Vous trouverez de nombreux tutoriels sur CSS sur Internet (les plus complets étant généralement en anglais). En voici quelques exemples : — http://www.w3schools.com/html/html_css.asp (en) 64 CHAPITRE 2. LE PAQUETAGE AGROSIXPACK — — — — — http://www.w3.org/TR/html401/present/styles.html (en) https://en.wikibooks.org/wiki/Cascading_Style_Sheets (en) https://fr.wikibooks.org/wiki/Le_langage_CSS (fr) http://fr.html.net/tutorials/css/ (fr) http://css.mammouthland.net/tutoriels-css.php (fr) Gardez à l’esprit qu’AgroSIXPack masque le code HTML, il faut donc utiliser les fonctions d’AgroSIXPack à la place du code HTML dans les tutoriels pré-cités. Il est possible d’ajouter une feuille de style avec la fonction : 1 // $feuille : string 2 function ajouter_feuille_css($feuille) où $feuille est le nom du fichier CSS relativement au répertoire courant. Pour appliquer un style particulier à une section d’affichage, on peut utiliser les fonctions : 1 // $style : string 2 function debut($style) et : 1 // $style : string 2 function fin($style = ’’) où $style est une classe CSS (sans le "." la précédant) définie dans une feuille de style utilisée par le fichier PHP courant. Ceci a pour effet d’encadrer le code d’une balise HTML <div>. Voici en exemple simple le fichier .php : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php ajouter_feuille_css(’style.css’); function main() { debut(’contenu’); afficher_titre(’Ceci est le titre’, 2); printline(’C\’est fabuleux d\’écrire en bleu !’); fin(’contenu’); } ?> Et le fichier "style.css" correspondant (à placer dans le même répertoire que le fichier .php) : 2.6. MODIFICATION DU STYLE 1 2 3 4 5 6 7 8 9 10 11 12 13 65 body { background-color: #eeffcc; } .contenu { color: darkblue; } .contenu h2 { font-style: italic; font-size: 24px; text-align: center; } Ceci a pour effet de changer la couleur de fond, d’afficher le texte écrit dans la section ’contenu’ en bleu foncé, et d’afficher le titre en italique, centré et de taille 24 pixels (et en bleu foncé). Chapitre 3 PHP/MySQL En PHP, il est très simple d’exécuter des requêtes SQL. Dans un même script PHP, l’utilisation de MySQL se fait en 4 temps : — Établissement d’une connexion générale à MySQL avec mysql_connect — Sélection d’une base de données avec mysql_select_db — Exécution des différentes requêtes avec mysql_query_affiche et traitement des réponses, souvent avec mysql_ligne_suivante — Fermeture de la connexion avec mysql_close 3.1 Connexion à la base de données La fonction : 1 2 3 4 // $server : string // $username : string // $password : string function mysql_connect($server, $username, $password) permet d’établir une connexion au serveur MySQL. C’est ce serveur qui fait l’interface entre PHP et la base de données. Il est donc nécessaire d’établir cette connexion. Lorsque la base de données est utilisée en local, c’est-à-dire que le même ordinateur sert à la fois de serveur PHP et de serveur MySQL (ce qui sera le cas pour vous), on utilise généralement cette fonction de cette manière : 1 mysql_connect(’localhost’, ’root’, ’mysql’) ; ou parfois : 1 mysql_connect(’localhost’, ’root’, ’’) ; selon la configuration du serveur MySQL. La fonction : 1 // $database_name : string 2 function mysql_select_db($database_name) 66 3.1. CONNEXION À LA BASE DE DONNÉES 67 permet de sélectionner la base de données $database_name. Avant d’effectuer des requêtes sur une base, il faut donc d’abord établir la connexion et sélectionner la base. 3.1.1 Exécution de requêtes SQL La fonction de base : 1 // $requete : string 2 // -> resource 3 function mysql_query($requete) demande au serveur MySQL d’exécuter la requête SQL $requete et renvoie son résultat sous forme d’une ressource, qui est donc une valeur de type resource. Cette fonction ne fait cependant pas de vérification sur la requête en cas d’erreur. Pour cela, une fonction de remplacement vous est fournie dans le paquetage AgroSIXPack : 1 // $requete : string 2 // -> resource 3 function mysql_query_debug($requete) qui fait la même chose que mysql_query mais affiche des messages d’erreur plus informatifs lorsque l’exécution de la requête n’a pas fonctionné. Le paquetage AgroSIXPack fournit aussi la fonction : 1 // $requete : string 2 // -> resource 3 function mysql_query_affiche($requete) qui fait la même chose que mysql_query_debug mais affiche en plus à l’écran la chaîne de caractères correspondant à la requête à exécuter. Ceci est très pratique pour visualiser rapidement d’où vient l’erreur, et permet aussi de tester la requête par un copier/coller dans phpMyAdmin. Vous devez donc utiliser mysql_query_affiche pour tester vos requêtes, et une fois que vous êtes assuré qu’elles fonctionnent correctement, vous pouvez utiliser mysql_query_debug pour éviter l’affichage. 3.1.2 Requêtes de type SELECT Pour les requêtes de type SELECT, il faut voir la ressource retournée comme une table résultat SQL, y compris lorsque l’on sait qu’une seule valeur est retournée ! Attention, ces ressources ne sont pas des tableaux PHP ; il faut utiliser des fonctions particulières pour en extraire le contenu. Pour lire le contenu de cette ressource donc, il faut parcourir la table résultat ligne par ligne, grâce à la fonction : 68 CHAPITRE 3. PHP/MYSQL 1 // $res : resource 2 // -> array 3 function mysql_ligne_suivante($res) qui prend en argument une ressource récupérée d’un appel précédent à mysql_query, et qui renvoie un tableau associatif PHP correspondant à la prochaine ligne de la table SQL résultat. 1 S’il n’y a pas de prochaine ligne dans le tableau, mysql_ligne_suivante renvoie false. Les clefs ou index du tableau sont les noms des colonnes de la table résultat demandés dans le SELECT, et les valeurs associées sont celles qui correspondent dans la table résultat. Exemple d’utilisation : 1 2 3 4 5 6 $res = mysql_query_affiche(’SELECT prenom, nom FROM personnes’); $ligne1 = mysql_ligne_suivante($res); if($ligne1) { printline(’prenom = ’ . $ligne1[’prenom’] . ’nom = ’ . $ligne1[’nom’]) ; } Ici, si la table personnes est vide, la valeur renvoyée par mysql_query_debug est une table résultat SQL $res vide, et le tout premier appel à mysql_ligne_suivante renvoie false ce qui signifie que $ligne1 prend la valeur false et on ne passe alors pas dans le corps du if. Si, au contraire, la table personnes contient au moins un enregistrement, le tableau résultat SQL $res n’est pas vide, et le premier appel à mysql_ligne_suivante renvoie le premier enregistrement de la table personne, qui est ainsi stocké dans la variable $ligne1 sous la forme d’un tableau associatif PHP. Le corps du if est alors exécuté car toute valeur différente de false, ’’ et 0 est considérée comme true (ainsi un tableau associatif est considéré comme true). Notez que dans l’exemple précédent, on ne s’est intéressé qu’à la première ligne de la table résultat SQL uniquement, et les autres lignes n’ont pas été traitées. Ceci est pratique lorsque l’on sait que l’on ne peut avoir que 0 ou 1 ligne de résultat de la requête. Mais si l’on veut traiter toutes les lignes de la table de résultat retournée par l’exécution de la requête de la même manière, on peut utiliser une boucle while : 1 2 3 4 5 6 7 $res = mysql_query_affiche(’SELECT prenom, nom FROM personnes’); $ligne = mysql_ligne_suivante($res); while($ligne) { printline(’prenom = ’ . $ligne[’prenom’] . ’nom = ’ . $ligne[’nom’]) ; $ligne = mysql_ligne_suivante($res); } Cet exemple affiche donc tous les résultats de la requête. Chaque nouvel appel à mysql_ligne_suivante renvoie un nouvel enregistrement de la table résultat SQL ; ceci signifie que les lignes précédentes du résultat sont perdues (à 1. mysql_ligne_suivante est un alias de mysql_fetch_assoc. 3.1. CONNEXION À LA BASE DE DONNÉES 69 moins d’être sauvegardées dans une variable PHP, ou de réexécuter la requête SQL). On dit que l’appel à mysql_ligne_suivante est destructif. L’exemple précédent peut s’écrire plus simplement, mais de manière équivalente : 1 $res = mysql_query_affiche(’SELECT prenom, nom FROM personnes’); 2 while($ligne = mysql_ligne_suivante($res)) { 3 printline(’prenom = ’ . $ligne[’prenom’] . 4 ’nom = ’ . $ligne[’nom’]) ; 5 } Notez que cette fois-ci, l’affectation de $ligne est fait dans le test de la boucle while, ce qui a pour effet à la fois de modifier la valeur de $ligne, et de tester que cette nouvelle valeur n’est pas false, sinon on arrête la boucle car il n’y a plus de ligne à traiter. 3.1.3 Autres types requêtes Pour les autres types de requêtes (UPDATE, INSERT INTO, DELETE, etc.), la ressource renvoyée est true ou false selon que la requête a pu être exécutée ou non. 3.1.4 Requêtes paramétrées : Échappement des apostrophes Dans une requête SQL, les valeurs sont encadrées par des apostrophes simples : 1 SELECT * FROM personnes WHERE nom=’Dupondt’ Mais si la valeur contient elle-même une apostrophe, il est nécessaire de l’échapper, c’està-dire de faire comprendre au langage qu’il ne s’agit pas de la fin de la chaîne de caractères, mais bien d’une caractère à l’intérieur de la chaîne, en faisant précéder l’apostrophe par un antislash ’\’ : 1 SELECT * FROM personnes WHERE nom=’l\’Autre’ En PHP, de telles valeurs proviennent généralement d’un formulaire, c’est-à-dire qu’elles sont données par l’utilisateur. Il devient alors nécessaire d’utiliser une méthode générale pour échapper automatiquement les apostrophes. Pour cela, on utilise la fonction mysql_real_escape_string : 1 // $str : string 2 // -> string 3 function mysql_real_escape_string($str) Par exemple, en supposant que la variable $nom contient une chaîne quelconque (probablement reçue d’un formulaire) : 1 $res = mysql_query_affiche(’SELECT * FROM personnes WHERE nom=\’’ . mysql_real_escape_string($nom) . ’\’’); L’utilisation de cette fonction est primordiale, car elle empêche aussi un utilisateur malveillant de pouvoir faire des injections SQL, c’est-à-dire de pouvoir faire des requêtes 70 CHAPITRE 3. PHP/MYSQL non-autorisées sur votre base de données, ce qui pourrait, par exemple, lui donner accès au mots de passes de tous les utilisateurs, ou lui permettre d’effacer entièrement la base. 2 Notez qu’il faut cependant échapper les apostrophes encadrant la valeur. Pour éviter cela, on peut aussi utiliser des apostrophes doubles pour les valeurs MySQL : 1 $nom = ...; 2 // la variable $nom contient une chaîne quelconque 3 $res = mysql_query_affiche(’SELECT * FROM personnes WHERE nom="’ . mysql_real_escape_string($nom) . ’"’); 4 ... Référez-vous aussi à la section 3.4.1 pour une simplification de ce mécanisme. 3.2 Fermeture de la connexion à la base Une fois que toutes les requêtes ont été traitées (et pas avant !), il faut fermer la connexion par un appel à la fonction : 1 function mysql_close() 3.3 Exemple complet Prenons l’exemple de la base ’client-commande’. Voici un programme demandant à l’utilisateur un nom partiel de client et qui affiche la liste des clients correspondants avec leur numéro de client et leur adresse. Le premier fichier, "mysql-client-form.php", est un simple formulaire : 1 <?php 2 3 function afficher_formulaire() { 4 5 debut_formulaire(’form_client’, ’mysql-client-trait.php’); 6 7 afficher_champ_texte(’nom’, ’Entrez un nom partiel de client : ’); 8 9 fin_formulaire(); 10 } 11 12 function main() { 13 14 afficher_formulaire(); 15 16 } 17 ?> 2. Pour plus d’informations : http://fr.wikipedia.org/wiki/Injection_SQL. 3.3. EXEMPLE COMPLET 71 L’accès à la base se fait ici dans le fichier de traitement de formulaire, "mysql-clienttrait.php", car on a besoin du nom du client pour effectuer la requête : 1 <?php 2 3 function afficher_clients($nom) { 4 // Création de la requête à partir du texte saisi par l’utilisateur 5 // Utiliser mysql_real_escape_string ! 6 // Recherche de tous les clients dont le nom contient $nom 7 $requete = ’SELECT nom, ncli, adresse FROM clients WHERE nom LIKE "%’ 8 . mysql_real_escape_string($nom) . ’%"’; 9 10 // Afficher la requête à l’écran, puis l’exécuter et 11 // récupérer la table SQL résultat 12 $res = mysql_query_affiche($requete); 13 14 // Afficher le résultats dans une liste 15 debut_liste(); 16 17 // parcourir la table SQL résultat, ligne par ligne : 18 while($ligne = mysql_ligne_suivante($res)) { 19 afficher_liste_item( 20 $ligne[’ncli’] . ’ ’ . 21 $ligne[’nom’] . ’ ’ . 22 $ligne[’adresse’]); 23 } 24 25 fin_liste(); 26 } 27 28 function traiter_formulaire() { 29 // Récupération du texte inscrit dans le champ ’nom’ 30 // par l’utilisateur à l’exécution *précédente* 31 // de ce fichier 32 $nom = valeur_champ(’nom’); 33 34 // Ouverture de la connexion au serveur MySQL 35 mysql_connect(’localhost’, ’root’, ’mysql’); 36 37 // Selection de la base de données 38 mysql_select_db(’client-commande’); 39 40 // Appel à la fonction d’affichage des prénoms 41 afficher_clients($nom); 42 43 // fermeture de la connexion à la base 44 mysql_close(); 45 } 46 47 function main() { 72 CHAPITRE 3. PHP/MYSQL 48 49 50 51 52 53 54 55 56 } 57 ?> $id_formulaire = get_id_formulaire(); // Traitement des données recues : if($id_formulaire === ’form_client’) { traiter_formulaire(); } 3.4 Autres fonctions utiles 1 // -> int 2 function mysql_insert_id() Retourne le numéro du dernier enregistrement, après une requête INSERT, dans le cas où la clef primaire est un entier auto-incrémenté. 3.4.1 Chaîne en SQL Pour éviter d’avoir à mettre des antislashs à chaque chaîne de caractères que l’on utilise dans une requête SQL, en plus d’appeler mysql_real_escape_string, on peut créer 3 une fonction qui fait cela à notre place : 1 2 3 4 5 // $chaine : string // -> string function chaine_en_sql($chaine) { return ’\’’ . mysql_real_escape_string($chaine) . ’\’’; } Ainsi, au lieu d’écrire : 1 $nom = ’Jean’; 2 $res = mysql_query_affiche(’SELECT * FROM personnes WHERE nom=\’’ . mysql_real_escape_string($nom) . ’\’’); on peut maintenant écrire plus simplement : 1 $nom = ’Jean’; 2 $res = mysql_query_affiche(’SELECT * FROM personnes WHERE nom=’ . chaine_en_sql($nom) ); Notez l’absence des \’ dans la seconde version. 3. Cette fonction n’existe pas de base et vous devez donc la créer vous-même si vous voulez l’utiliser. 3.5. POUR ALLER PLUS LOIN 73 Attention, il ne faut appeler cette fonction que si l’on souhaite mettre des guillemets autour de la valeur (ou la variable) passée en argument, c’est-à-dire si cette valeur est censée être une chaîne de caractères dans la requête. Il ne faut donc pas utiliser cette fonction pour les nombres par exemple (mais il faut cependant toujours utiliser mysql_real_escape_string, même pour les nombres). Remarque : Pour éviter de dupliquer cette fonction dans chaque fichier où vous pourriez l’utiliser, il est fortement conseillé de la définir dans un fichier à part, par exemple outils.php, puis “d’inclure” ce fichier dans chaque fichier php où vous voudriez l’utiliser en ajoutant dans ces derniers : 1 2 3 4 5 6 <?php include(’outils.php’); ... ?> juste en dessous <?php, et donc avant toute définition de fonction. On peut évidemment ajouter d’autres fonctions utiles dans outils.php. 3.4.2 Noms et identifiants dans une liste déroulante Il est courant de vouloir afficher une liste déroulante de noms tirés d’une base de données par une requête, tout en voulant envoyer au fichier de traitement de formulaire non pas le nom sélectionné par l’utilisateur mais l’identifiant correspondant. Le schéma habituel (que l’on peut déduire de tout ce qui précède) est alors le suivant : 1 2 3 4 5 6 7 8 9 10 11 12 $requete = ’SELECT nom, id FROM ma_table’; $res = mysql_query_affiche($requete); debut_select(’nom_id’); while($ligne = mysql_ligne_suivante($res)) { // afficher le nom, mais envoyer l’identifiant afficher_select_item($ligne[’nom’], $ligne[’id’]); } fin_select(); 3.5 Pour aller plus loin Pour des informations plus complètes sur les fonctions MySQL en PHP, vous pouvez consulter la page web : http://www.php.net/manual/fr/ref.mysql.php. Chapitre 4 Travaux Dirigés PHP 74 75 TD 1 : Valeurs, expressions, variables, conditionnelle Pour effectuer ces exercices, vous devez avoir travaillé les pages 7 à 22 avant de venir en TD. Exercice 1 : Premiers pas avec l’évaluateur En premier lieu, il vous faut installer AgroSIXPack. Téléchargez AgroSIXPack.exe à l’adresse suivante : http://gaia.agroparistech.fr/~orseau et suivez les instructions en conservant les paramètres par défaut (si vous êtes dans une salle de TD, mais si vous l’installez sur votre poste personnel, suivez les instructions page 122). Chaque TD a donc son propre répertoire, et pour aujourd’hui tous les exercices se trouvent dans TD1. Exercice 2 : Premiers pas 1. Commencez par lancer EasyPHP à partir du menu démarrer. 2. Tapez ensuite l’adresse suivante dans votre navigateur : http://localhost/www/PHP 3. Cliquez sur "Evaluateur" (dans le bandeau de la page, en petit) 4. Dans le cadre de gauche, écrivez : 1 printline(’Bonjour le monde !’); 5. Cliquez ensuite sur "Evaluer". Ceci a pour effet de dire à PHP d’exécuter votre programme. Vous devez alors voir apparaître votre texte dans le cadre de droite "Résultat :". Par la suite, vous devrez remplacer ou modifier le contenu du cadre de gauche, et cliquer sur "Evaluer" à chaque fois que vous voudrez voir le résultat. Exercice 3 : Types et expressions Question 1 : Pour chacune des expressions suivantes, sans utiliser l’évaluateur, devinez et écrivez le type et la valeur résultants de l’expression. Dans un deuxième temps, utilisez l’évaluateur pour vérifier votre réponse, en utilisante infos_expr (voir page 12). 76 CHAPITRE 4. TRAVAUX DIRIGÉS PHP 1 42 Type : Valeur : 1 -3.14 Type : Valeur : 1 10+5.2/4*3 Type : Valeur : 1 printline(10+5.2/4*3) Type : Valeur : 1 strval(42) Type : Valeur : 1 intval(’42.5’)+floatval(’2.5’) Type : Valeur : 1 ’100’ . ’-50’ Type : Valeur : 1 4 < 2 || 5 < 7 Type : Valeur : 1 ’cec’ . ’i es’ . ’t une chaîne’ Type : Valeur : 1 printline(’Bonjour !’) Type : Valeur : 1 ’123’ === 123 Type : 1 intval(’123’) === 123 Valeur : 77 Type : Valeur : 1 ’au revoir’ !== false Type : Valeur : 1 ’bon’ . ’soir’ === ’bonjour’ || ’au revoir’ !== false Type : Valeur : Question 2 : Pour chacune des instructions suivantes et en vous aidant de l’évaluateur, expliquez l’erreur que PHP génère, à quoi elle est due, et donnez l’instruction corrigée : 1 printline(’Il est l’heure’); Correction : 1 printline(’Mon’. seigneur’ ); Correction : 1 printline(’Un peu de texte’) Correction : Exercice 4 : Variables et affectations Question 1 : Sans utiliser l’évaluateur, pour chacun des groupes d’instructions, donnez le type et la valeur de la variable $var à la fin du groupe d’instructions : 1 $var = 1664; 2 $var += 335; 3 $var = ’1664’; Type : Valeur : 1 $var = false; 2 $var = ($var && true) || ($var === ’false’); Type : Valeur : 78 CHAPITRE 4. TRAVAUX DIRIGÉS PHP 1 $var = ’Jean’; 2 $var .= ’ ’ . $var; Type : Valeur : Utilisez ensuite l’évaluateur pour vérifier vos résultats. Question 2 : Pour chacune des instructions suivantes et en vous aidant de l’évaluateur, expliquez l’erreur que PHP génère, à quoi elle est due, et donnez l’instruction corrigée : 1 1664 = $nombre; Correction : 1 $phrase = ’Robinson fit le tour de l’île’; Correction : 1 mois = ’Juillet’; Correction : 1 $annee += 10; Correction : 1 $jour = ’Vendredi’ Correction : 1 $prenom = Gonzales; Correction : Exercice 5 : Conditionnelle Question 1 : Écrivez une instruction permettant de tirer aléatoirement un nombre entre 1 et 100 et de le stockez dans la variable $age. Pour cela, vous utiliserez la fonction prédéfinie rand (voir sa description en annexe A.1.3). Affichez le contenu de la variable : Age: 21 ans 79 Question 2 : Complétez votre programme pour afficher : Vous êtes un adulte dans le cas où l’âge tiré aléatoirement est supérieur ou égal à 18. Question 3 : Complétez votre programme pour afficher, en plus de précédemment : Vous êtes un enfant dans le cas où l’âge tiré aléatoirement est inférieur à 18. Question 4 : En suivant les lignes de conduite données en annexe B, modifiez votre programme pour afficher : Vous êtes un enfant si l’âge est inférieur à 10, Vous êtes un adolescent si l’âge est compris entre 10 et 17, Vous êtes un adulte si l’âge est compris entre 18 et 49, Vous êtes un vétéran si l’âge est supérieur ou égal à 50. Question 5 : Reprenez la question précédente et faites en sorte de n’avoir que 3 inégalités, mais votre programme doit rester équivalent. Indice : Utilisez les else if. Exercice 6 : [Bonus] Diviseurs Question 1 : Écrivez un programme qui tire 3 nombres aléatoirement entre 1 et 20 compris, qui les affiche à l’écran, et qui affiche ’oui’ une seule et unique fois si l’un des nombres est diviseur d’un des 2 autres nombres, ou ’non’ dans le cas contraire. 80 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Vous pouvez utiliser l’opérateur modulo %, mais attention, un nombre est diviseur d’un autre seulement s’ils sont différents l’un de l’autre et différents de 1. Exemples d’affichage du programme : n1 = 6 n2 = 8 n3 = 2 oui n1 = 3 n2 = 7 n3 = 5 non n1 = 1 n2 = 4 n3 = 4 non n1 = 1 n2 = 4 n3 = 16 oui Vérifiez bien que votre programme fonctionne correctement en faisant les calculs vous-mêmes en fonction des valeurs affichées à l’écran (rafraîchissez la page avec la touche F5 de votre clavier). Vérifiez aussi qu’il fonctionne correctement en remplaçant les nombres aléatoires par les valeurs données dans les exemples ci-dessus. Question 2 : Modifiez votre programme précédent pour qu’il n’utilise qu’un seul et unique if et else. 81 TD 2 : Fonctions et variables Pour effectuer ces exercices, vous devez avoir travaillé les pages 23 à 36 avant de venir en TD. L’évaluateur est pratique pour effectuer de petits tests (et n’hésitez pas à vous en resservir), mais il est limité et il devient vite fastidieux d’y créer des programmes plus conséquents. À partir de maintenant, nous utiliserons un éditeur de texte (Notepad++), nous permettant de sauvegarder ce que nous taperons dans un fichier, en profitant de plus de la coloration syntaxique, rendant les programmes beaucoup plus lisibles. Vous pourrez aussi maintenant utiliser la touche "tabulation" pour indenter votre programme (lire l’annexe B page 118). Exercice 1 : Premier programme 1. Commencez par lancer EasyPHP à partir du menu démarrer. 2. Ouvrez ensuite Notepad++ à partir du menu démarrer. Puis, dans Notepad++, ouvrez le fichier : N :\www\PHP\TD2\exo1.php Complétez la fonction main avec le code PHP suivant : 1 printline(’Bonjour le monde !’); N’oubliez pas de sauvegarder votre fichier, sinon les changements ne seront pas pris en compte. 3. Tapez ensuite l’adresse suivante dans votre navigateur : http://localhost/www/PHP/AgroSIXPack.php puis choisissez le fichier "exo1.php" sous le dossier "TD2". Ceci a pour effet d’exécuter le fichier "exo1.php" dans le navigateur. 4. Modifiez votre programme pour qu’il affiche maintenant : Bonjour le monde ! Au revoir le monde. Remarque : Une fois votre fichier "exo1.php" modifié, il vous suffit dans le navigateur de cliquer sur "Actualiser" ou d’appuyer sur F5 pour recharger le fichier sans avoir à repasser par la page d’accueil d’AgroSIXPack. Exercice 2 : Correction d’erreurs Depuis AgroSIXPack, exécutez le fichier "exo3.php" dans le navigateur. Chaque fonction (hormis la fonction main) comporte une et une seule erreur. À son exécution, l’affichage des résultats est incorrect, et PHP vous affiche un message d’aver- 82 CHAPITRE 4. TRAVAUX DIRIGÉS PHP tissement vous indiquant que ce fichier est erroné. Lisez bien le message d’erreur et comprenez-le entièrement. Question 1 : Modifiez chacune des 3 fonctions somme, l’une après l’autre, sans toucher au main, de façon à ce que l’exécution de votre programme affiche exactement : Somme1 : 25 Somme2 : 29 Somme3 : 31 tout en respectant les commentaires des signatures de fonctions. Exercice 3 : Fonction de concaténation de chaînes de caractères Question 1 : Dans le fichier N :\www\PHP\TD2\exo4.php, écrivez la fonction entourer dont voici la signature : 1 2 3 4 // $chaine1 : string // $chaine2 : string // -> string function entourer($chaine1, $chaine2) Qui prend en argument 2 chaînes de caractères et qui retourne la chaîne $chaine1 entourée à gauche et à droite par la chaîne $chaine2. Une fois la fonction écrite, exécutez le fichier "exo4.php" pour vérifier qu’il est correct. Vous devez obtenir exactement : Voici le dilemme : être ou ne pas être Remarque : Vous ne devez pas modifier la fonction principale. Question 2 : En utilisant exactement un seul appel à printline, deux appels à la fonction entourer, deux fois la chaîne "X" et une seule fois la chaîne "a", écrivez le code permettant d’afficher : aXaXaXa Question 3 : En utilisant exactement un seul appel à printline, trois appels à la fonction entourer, trois fois la chaîne "X" et une seule fois la chaîne "a", écrivez le code permettant d’afficher : 83 aXaXaXaXaXaXaXa Exercice 4 : Fonctions Ouvrez le fichier N :\www\PHP\TD2\exo5.php et exécutez-le pour voir le résultat. Question 1 : Modifiez ce programme (y compris le main) de manière à afficher la même chose, mais en utilisant une fonction (que vous devrez créer) : 1 // $racine : string 2 function conjuguer($racine) qui prend en argument une racine de verbe sous forme de chaîne de caractères et affiche la conjugaison d’un seul verbe. Le programme final doit alors être plus court que le programme initial. Question 2 : Ajoutez la conjugaison du verbe ’labourer’. Exercice 5 : Variables locales Ouvrez le fichier N :\www\PHP\TD2\var-locales.php. Les comportements que vous allez observer sur les variables sont des notions très importantes de programmation. Ils sont propres à de nombreux langages, il est important de bien les comprendre. Question 1 : Dans la fonction main, après l’affectation des variables, ajoutez l’affichage de leur valeur par : 1 printline(’a = ’ . $a . ’ b = ’ . $b) ; Et exécutez ce fichier pour visualiser le résultat. Question 2 : Juste en dessous de ce que vous venez d’écrire, ajoutez l’appel suivant à la fonction : fun1 1 fun1($a); Exécutez le fichier et vérifiez si ce qui est affiché correspond bien à votre intuition. 84 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Question 3 : Ajoutez encore en-dessous un nouvel affichage : 1 printline(’a = ’ . $a . ’ b = ’ . $b) ; À nouveau, vérifiez que le résultat est bien conforme à votre intuition. Consultez la section 1.9.2 dans le cas contraire. Question 4 : Ajoutez enfin : 1 fun1($b); 2 3 printline(’a = ’ . $a . ’ b = ’ . $b) ; et vérifiez une dernière fois que vous avez bien compris comment fonctionnent les variables locales. Exercice 6 : Multilinguisme Ouvrez le fichier "langues.php" (et non "langues-form.php") dans Notepad++ et exécutez-le dans le navigateur. Vous êtes automatiquement redirigé vers un formulaire de choix de langues. Lorsque vous appuyez sur le bouton "Ok", ceci a pour effet d’exécuter le fichier "langues.php" en lui envoyant des valeurs, que vous pouvez récupérer grâce à valeur_checkbox dans la fonction traiter_formulaire, qui sera exécutée automatiquement (car appelée dans la fonction main). Vous n’avez pas besoin de modifier la fonction main. Question 1 : En suivant le modèle fourni dans le fichier, modifiez la fonction compter_langues pour compter et retourner le nombre de langues parlées par l’utilisateur. Dans la fonction traiter_formulaire, faites un appel à la fonction compter_langues et récupérez la valeur de retour dans une variable $nb_langues. Ajoutez un affichage dans cette fonction traiter_formulaire (mais pas dans compter_langues) pour obtenir par exemple : Vous parlez 2 langue(s). en fonction du nombre de langues effectivement parlées. 85 Question 2 : Modifiez la fonction traiter_formulaire pour afficher l’une des phrases suivantes en fonction du nombre de langues parlées : "Vous ne parlez aucune langue, j’ai du mal à y croire." ou bien "Vous ne savez parler qu’une seule langue, c’est peu...", ou bien "Vous êtes dans la moyenne." (pour 2 ou 3 langues parlées), ou bien "Impressionnant." (pour 4 langues parlées). Question 3 : Supprimez les affichages dans la fonction compter_langues : ils n’étaient là qu’à titre informatif et les fonctions qui retournent des valeurs ne doivent en général pas faire d’affichage. Modifiez le code écrit à la question précédente de manière à n’utiliser qu’un seul et unique printline, qui doit être dans votre fonction traiter_formulaire, sans que cela modifie le comportement de votre programme. 86 CHAPITRE 4. TRAVAUX DIRIGÉS PHP TD 3 : Boucles Pour effectuer ces exercices, vous devez avoir travaillé les pages 37 à 41 avant de venir en TD. Tous les exercices de ce TD se trouvent dans votre répertoire N :\www\PHP\TD3. Remarque : Dans ce TD, nous voyons les boucles, vous ne devez donc pas énumérer les différents cas possibles un par un ; il faut chercher à faire des solutions générales, qui fonctionnent quelque soit le nombre de traitements individuels à faire. Exercice 1 : 99 Bouteilles de bière La chanson "99 bottles of beer" est un chant traditionnel américain. Nous allons le programmer lorsque le nombre de bouteilles initial est donné par l’utilisateur. Question 1 : En utilisant une boucle while, modifiez la fonction traiter_formulaire dans le fichier "bouteilles.php" pour lui faire afficher le résultat suivant, ici dans le cas où le nombre de bouteilles entré est 3 : 3 bottles of beer on the wall, 3 bottles of beer. Take one down, pass it around, 2 bottles of beer on the wall. 2 bottles of beer on the wall, 2 bottles of beer. Take one down, pass it around, 1 bottles of beer on the wall. 1 bottles of beer on the wall, 1 bottles of beer. Take one down, pass it around, 0 bottles of beer on the wall. No more bottles of beer on the wall, go to the store and buy some more. Remarque : Il n’est pas nécessaire de traiter les cas particuliers des singuliers pour 0 et 1. Exercice 2 : Triangle Ouvrez le fichier "triangle.php". Dans cet exercice, à chaque nouvelle question, vous devrez décommenter (c’est-à-dire retirer les commentaires), dans le main, les tests correspondants à la question courante. Vous pourrez aussi ajouter vous-mêmes des tests supplémentaires (mais utilisez au moins ceux qui sont fournis) pour vous assurer du bon fonctionnement de vos fonctions. 87 Question 1 : Créez une fonction : 1 // $long : int 2 // -> string 3 function ligne_etoiles($long) qui prend en argument une longueur $long et retourne un chaîne de caractères (string) composée d’un nombre $long d’étoiles ’*’. Attention, cette fonction ne doit rien afficher (c’est-à-dire qu’elle ne doit pas utiliser de fonction d’affichage telle que printline ou print), mais seulement retourner une valeur (en utilisant return donc). Tous les affichages seront faits dans la fonction main. Décommentez dans le main les premiers tests correspondants aux appels à la fonction ligne_etoiles, et qui affichent le résultat. Exemple : 1 printline(ligne_etoiles(10)); Résultat : ********** Question 2 : Créez une fonction : 1 // $long : int 2 // -> string 3 function carre_etoiles($long) qui, en faisant un appel à la fonction ligne_etoiles, retourne une chaîne de caractères composée de $long sur $long étoiles. Testez votre nouvelle fonction en décommentant les tests correspondants. Exemple : 1 printline(carre_etoiles(5)); Résultat : ***** ***** ***** ***** ***** Vous aurez besoin de la fonction newline qui retourne une chaîne de caractères représentant un passage à la ligne. Exemple d’utilisation : 1 printline(’abc’ . newline() . ’def’ . newline() . ’ghi’); affiche : 88 CHAPITRE 4. TRAVAUX DIRIGÉS PHP abc def ghi Question 3 : Créez une fonction : 1 // $long : int 2 // -> string 3 function triangle_etoiles($long) qui, en faisant appel à la fonction ligne_etoiles, retourne une chaîne de caractères représentant un triangle de base $long étoiles. Exemple : 1 printline(triangle_etoiles(6); Résultat : ****** ***** **** *** ** * Question 4 : Deux boucles for Créez une fonction : 1 // $long : int 2 // -> string 3 function triangle_deux_for($long) qui fait exactement la même chose que triangle_etoiles, mais en utilisant 2 boucles for au lieu d’appeler la fonction ligne_etoiles. Attention, lorsque vous testerez votre fonction, prenez garde à bien faire appel à triangle_deux_for et non à triangle_etoiles ! Question 5 : Deux boucles while Créez une fonction : 1 // $long : int 2 // -> string 3 function triangle_deux_while($long) qui fait exactement la même chose que triangle_deux_for, mais en remplaçant les 2 boucles for par des boucles while, et toujours sans faire appel aux fonctions précédentes. 89 Question 6 : [Bonus] Une boucle while Créez une fonction : 1 // $long : int 2 // -> string 3 function triangle_un_while($long) qui fait exactement la même chose que triangle_deux_while, mais cette fois en utilisant un seul et unique while, et aucune autre structure de boucle (donc aucun for). Remarque : Vous pouvez utiliser la structure if par contre. 90 CHAPITRE 4. TRAVAUX DIRIGÉS PHP TD 4 : Tableaux et boucles Pour effectuer ces exercices, vous devez avoir travaillé les pages 42 à 51 avant de venir en TD. Exercice 1 : Manipulation de tableaux Ouvrez le fichier "tableaux.php". Question 1 : Affichage En utilisant une boucle while, for ou foreach, et sans avoir recours à print_r, SI_print_r ou afficher_table_ligne, créez une fonction : 1 // $tableau : array(any) 2 function afficher_tableau($tableau) qui affiche les éléments d’un tableau à l’écran, sur une même ligne. Exemple d’utilisation : 1 function main() { 2 $tab = array(87, 28, 67, 71, 25, 53, 45, 3, 47, 48); 3 afficher_tableau($tab); 4 afficher_tableau(array(’un’, ’deux’, ’trois’)); 5 } Ceci doit afficher : 87 28 67 71 25 53 45 3 47 48 un deux trois Rappel : La fonction printline affiche une valeur à l’écran puis passe à la ligne, alors que la fonction print affiche une valeur à l’écran sans passer à la ligne. Question 2 : Créez une fonction : 1 // $n : int 2 // -> array(int) 3 function creer_tableau_alea($n) qui retourne un tableau de $n nombres, chaque nombre étant compris entre 1 et 100. Exemple d’utilisation : 1 function main() { 2 $tab = creer_tableau_alea(10); 3 afficher_tableau($tab); 4 } 91 Ceci doit afficher (moyennant les nombres aléatoires tirés) : 80 77 10 75 98 30 28 13 11 63 Vous utiliserez la fonction rand (cf. A.1.3). Question 3 : Décompte Créez une fonction : 1 2 3 4 // $tableau : array(int) // $entier : int // -> int function compte($tableau, $entier) qui retourne le nombre de fois que l’entier $entier apparaît dans le tableau $tableau. Exemple d’utilisation : 1 function main() { 2 $tab = array(8, 2, 8, 5, 3 printline(’nombre de 8 : 4 printline(’nombre de 2 : 5 printline(’nombre de 9 : 6 } 4, 8, 2, 3); ’ . compte($tab, 8)); ’ . compte($tab, 2)); ’ . compte($tab, 9)); Ceci doit afficher : nombre de 8 : 3 nombre de 2 : 2 nombre de 9 : 0 Exercice 2 : Jeux de mots Ouvrez le fichier "phrases.php". L’objectif de cet exercice est de créer aléatoirement des phrases relativement simples. Aucun affichage ne devra être présent dans les fonctions autres que le main. Question 1 : Créez la fonction main. Définissez-y un tableau nommé $objets de 7 éléments, contenant 3 prénoms ainsi que 4 noms communs précédés d’un article (’une clef’, ’la table’, etc.). Question 2 : Choix d’un élément Faites une fonction : 92 CHAPITRE 4. TRAVAUX DIRIGÉS PHP 1 // $tableau : array(string) 2 // -> string 3 function choix_element($tableau) qui prend en argument un tableau de chaînes de caractères et qui renvoie un élément pris au hasard dans ce tableau. Par exemple, l’appel : 1 printline(choix_element(array(’un’, ’deux’, ’trois’))); peut afficher soit ’un’, soit ’deux’, soit ’trois’. Faites quelques tests de cette fontion sur le tableau $objets dans la fonction main pour vérifier qu’elle fonctionne correctement. Une fois que vous en êtes satisfaits, mettez ces tests en commentaire (avec //). Rappel : le premier indice d’un tableau est le 0. Rappel : la fonction count permet de connaître le nombre d’éléments d’un tableau. Question 3 : Verbes Dans la fonction main, ajouter un tableau $verbes contenant 4 verbes transitifs directs, conjugués à la 3ème personne du singulier (par exemple ’mange’, ’jette’, etc.) 1 . (Il n’y a rien d’autre à faire dans cette question.) Rappel : Un verbe transitif direct est un verbe qui accepte un complément d’objet direct, comme ’prendre’, ’déraciner’, etc. Question 4 : Faites une fonction : 1 2 3 4 // $tab_objets : array(string) // $tab_verbes : array(string) // -> string function creer_phrase($tab_objets, $tab_verbes) qui prend en argument un tableau d’objets (directs ou indirects) et un tableau de verbes conjugués et qui, en utilisant la fonction choix_element, renvoie une phrase créée aléatoirement. Une phrase est composée d’un sujet, d’un verbe et d’un complément d’objet. Par exemple, le code suivant : 1. Vous pouvez utiliser des verbes transitifs indirects à condition de les faire suivre d’une préposition, par exemple ’pose sur’. 93 1 function main() { 2 $objets = array(’Pierre’, ’un mouton’, ...); 3 $verbes = array(’questionne’, ...); 4 5 $phrase = creer_phrase($objets, $verbes); 6 printline($phrase); 7 } doit pouvoir afficher : Pierre questionne un mouton Remarque : creer_phrase ne doit ne doit toujours pas utiliser de fonction d’affichage (printline, etc.), mais doit retourner une valeur. Dans la fonction main, faites un appel à la fonction creer_phrase et faites-lui afficher la phrase ainsi obtenue. Vous pouvez exécuter le programme plusieurs fois en appuyant sur F5 dans le navigateur. Question 5 : Subordonnée Écrivez une fonction : 1 2 3 4 // $tab_objets : array(string) // $tab_verbes : array(string) // -> string function creer_proposition($tab_objets, $tab_verbes) qui prend en argument un tableau d’objets et un tableau de verbes conjugués et qui renvoie une proposition subordonnée aléatoire commençant par ’ qui ...’. Par exemple : qui mange un canapé Modifiez la fonction creer_phrase pour afficher une phrase avec une subordonnée. Par exemple : Pierre questionne un mouton qui mange un canapé Question 6 : [Bonus] Cette question est à faire à la fin du TD uniquement si vous avez fini tout le reste. Modifiez la fonction creer_phrase précédente pour lui faire écrire une phrase composée d’un nombre aléatoire (entre 1 et 5) de propositions adjointes par la préposition "qui". Par exemple : Pierre questionne un mouton qui mange un canapé qui compresse un lapin Remarque : Ici, vous devez utiliser une boucle. 94 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Exercice 3 : [Bonus] Vente en ligne Ouvrez le fichier "articles.php". Dans le formulaire de "vente en ligne", l’utilisateur doit saisir 5 articles et leur prix. Dans votre fichier "articles.php", dans la fonction traiter_formulaire, vous récupérez deux variables $articles et $prix, qui sont des tableaux scalaires. Question 1 : Dans la fonction traiter_formulaire, utilisez la fonction afficher_tableau définie dans un exercice précédent pour afficher le contenu des deux tableaux. Question 2 : Faites une fonction : 1 // $tab_prix : array(real) 2 // -> real 3 function prix_total($tab_prix) qui retourne le total des prix contenus dans le tableau $tab_prix passé en argument. Question 3 : Écrivez une fonction : 1 // $tab_articles : array(string) 2 // $tab_prix : array(real) 3 function afficher_ticket($tab_articles, $tab_prix) permettant de récapituler les informations saisies sous une forme plus agréable que par afficher_tableau. Affichez en dessous le prix total calculé. Voici un exemple d’une partie de l’affichage de la table : Article : Prix -------------Pommes : 1.20 Yaourts : 2.49 Chocolat : 48.15 ... -------------Total : 125.77 Remarque : Ne cherchez par à aligner les " :". Remarque : Le total affiché doit évidemment être un appel à la fonction prix_total définie plus haut. 95 Note : Pour un affichage encore plus clair, vous pouvez utiliser les fonctions debut_table , fin_table, debut_table_ligne, fin_table_ligne et afficher_table_donnee (cf. section 48). Mais ne perdez pas trop de temps avec cela. Question 4 : Faites une fonction : 1 // $tab_prix : array(real) 2 // -> string 3 function article_plus_cher($tab_prix) qui retourne l’indice de l’article le plus cher que vous avez acheté. Modifiez la fonction afficher_ticket pour lui faire afficher aussi l’article le plus cher avec son prix : Article : Prix -------------Pommes : 1.20 Yaourts : 2.49 Chocolat : 48.15 ... -------------Total : 125.77 Article le plus cher : Chocolat : 48.15 Question 5 : [Bonus] Tri Modifiez les fonctions précédentes pour afficher, sur le ticket, les produits par ordre décroissant de prix. 96 CHAPITRE 4. TRAVAUX DIRIGÉS PHP TD 5 : Formulaires 1 Pour effectuer ces exercices, vous devez avoir travaillé les pages 51 à 62 avant de venir en TD. Exercice 1 : Formulaires Nous allons commencer par créer un formulaire simple pour comprendre comment les informations sont passées d’une page PHP à l’autre. Cet exercice est similaire à l’exemple de la page 58. Nous utilisons deux fichiers : — "exo1-formulaire.php" sert à afficher le formulaire et ses champs (champ de texte, boutons, cases à cocher, etc.), pour que l’utilisateur y saisisse des valeurs avant de cliquer sur le bouton "OK" ; — "exo1-traitement.php" sert à traiter (recevoir et utiliser, par exemple afficher) les données saisies par l’utilisateur dans le formulaire. Question 1 : Dans le fichier "exo1-traitement.php", créez la fonction main, et ajoutez-y l’affichage suivant : 1 printline(’Dans le main de exo1-traitement.php’); Exécutez votre fichier qui doit donc afficher le message ci-dessus. Question 2 : 1. Dans le fichier "exo1-formulaire.php", créez une fonction : 1 function afficher_formulaire() qui affiche un formulaire d’identifiant ’questionnaire’ et de page de destination "exo1-traitement.php", en utilisant les fonctions debut_formulaire et fin_formulaire (voir page 52). Remarque : Pour le moment, il n’y a rien à mettre entre ces deux appels de fonction. 2. Créez la fonction main et ajoutez-y un appel à la fonction afficher_formulaire. 3. Exécutez le fichier "exo1-formulaire.php". Ceci affiche le bouton de validation du formulaire. 4. Cliquez sur le bouton. Ceci vous amène sur la page "exo1-traitement.php" et affiche le message correspondant. 97 Question 3 : Entre l’appel à debut_formulaire et fin_formulaire, ajoutez un champ texte d’identifiant ’prenom’ demandant le prénom de l’utilisateur, en utilisant afficher_champ_texte (voir page 53). L’identifiant du champ texte est la valeur donnée en argument à afficher_champ_texte pour l’argument d’entrée $id_champ. Exécutez le fichier, entrez un prénom puis validez le formulaire en cliquant sur le bouton. Question 4 : Dans le fichier "exo1-traitement.php", nous allons maintenant récupérer les données que l’utilisateur saisit dans le formulaire. 1. Créez la fonction : 1 function traiter_formulaire() et ajoutez-y un affichage pour vérifier que la fonction est bien exécutée, tel que : 1 printline(’Dans traiter_formulaire()’); 2. Ajouter un appel à cette fonction dans la fonction main. 3. Exécutez le formulaire et cliquez sur le bouton. Les deux messages : Dans le main de exo1-traitement.php Dans traiter_formulaire() doivent s’afficher. 4. Modifiez la fonction traiter_formulaire pour récupérer le prénom saisi par l’utilisateur grâce à un appel à la fonction valeur_champ (voir page 58) en lui passant en argument l’identifiant du champ texte ’prenom’. Sauvegardez la chaîne de caractères ainsi récupérée dans une variable $prenom. Référez-vous à l’exemple page 58. Attention, les $id_champ ne doivent contenir ni espace, ni accent, ni caractère spécial (pour éviter tout problème, utiliser uniquement des lettres, chiffres et "_"). Affichez-y ensuite le récapitulatif des informations saisies par l’utilisateur : Prénom : Albert. 5. Exécutez le formulaire, remplissez le champ texte avec un prénom et cliquez sur le bouton. Vous devez maintenant voir affiché le prénom saisi. Question 5 : Dans le formulaire, ajoutez un groupe radio pour demander le sexe H/F de l’utilisateur. Dans le traitement du formulaire, ajoutez la récupération des données du formulaire pour ce nouveau champ. Modifiez le récapitulatif des informations saisies par l’utilisateur en conséquence. 98 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Question 6 : Dans le formulaire, ajoutez une liste de choix (champ select) demandant le style musical préféré, en utilisant debut_select (voir page 55) et consors. Ajoutez-y un quelques styles musicaux selon vos goûts. Modifiez le traitement du formulaire en conséquence, ainsi que le récapitulatif des informations saisies. Question 7 : Ajoutez une checkbox seule avec afficher_checkbox (voir page 53) (et non un groupe checkbox) demandant à l’utilisateur s’il est lui-même musicien, et modifiez le traitement du formulaire en conséquence en utilisant valeur_checkbox (voir page 60), pour afficher ’Vous êtes musicien’ ou ’Vous n\’êtes pas musicien’ selon le choix de l’utilisateur. Question 8 : Ajoutez un groupe checkbox en utilisant debut_groupe_checkbox (voir page 53) et consors pour demander à l’utilisateur de quels instruments il a déjà joué (choisissez quelques instruments selon vos goûts). Modifiez le traitement du formulaire en conséquence en utilisant valeur_champ (voir 2.4.2 page 60) pour afficher par exemple Vous avez jouéde cet instrument: Piano pour chaque instrument coché par l’utilisateur. Question 9 : Exécutez directement le fichier "exo1-traitement.php", sans passer par le formulaire. Cela affiche des informations incohérentes car l’appel à la fonction traiter_formulaire suppose qu’il y a bien un formulaire avec des données associées à traiter. Il faut donc prendre en compte ce cas particulier en vérifiant que l’on est bien passé par le formulaire. 1. Dans le main du fichier "exo1-traitement.php", récupérez le nom du formulaire qui a été traité (le cas échéant) : 1 function main() { 2 $id_formulaire = get_id_formulaire(); 3 ... 4 } 2. La variable $id_formulaire aura pour valeur l’identifiant du formulaire qui a envoyé les données à "exo1-traitement.php" (cette valeur sera donc ’questionnaire’ ici, si on est passé par le formulaire du fichier "exo1-formulaire.php") ou la valeur false si on n’est pas passé par un formulaire. Utilisez cette valeur pour appeler la fonction traiter_formulaire, ou affichez ’Aucun formulaire traité’ le cas échéant. 99 3. Exécutez à nouveau le fichier "exo1-traitement.php" directement : il ne doit plus s’afficher d’erreur car la fonction traiter_formulaire ne doit pas être appelée. 4. Exécutez le fichier "exo1-formulaire.php" et validez le questionnaire pour vérifier que les données sont toujours bien envoyées et traitées par le formulaire. 5. Ajoutez un lien interne avec afficher_lien_interne (voir page 50) pour rediriger l’utilisateur vers la page du formulaire, dans le cas où l’on n’est pas passé par un formulaire. 100 CHAPITRE 4. TRAVAUX DIRIGÉS PHP TD 6 : Formulaires 2 et Sessions Exercice 1 : ADN Nous voulons faire un formulaire demandant à l’utilisateur une taille de séquence ADN à générer aléatoirement, ainsi qu’une sous-séquence à chercher dans cette séquence. Comme précédemment, il y a deux fichiers : — Le fichier "adn-formulaire.php" sert uniquement à afficher un formulaire demandant des informations à l’utilisateur. — Le fichier "adn-traitement.php" sert pour tout le reste, notamment la réception des données saisies par l’utilisateur dans les champs du formulaire, ainsi que le traitement de ces données et les calculs associés. Nous n’allons pas tout de suite créer de formulaire et nous commençons par créer les fonctions de calcul, dans le fichier "adn-traitement.php". Question 1 : Dans le fichier "adn-traitement.php", créez la fonction main. Question 2 : Créez une fonction : 1 // $taille : int 2 // -> array(string) 3 function generer_ADN($taille) qui renvoie une séquence ADN de taille $taille sous forme d’un tableau de caractères (chaque case doit être un acide aminé ’A’, ’C’, ’T’ ou ’G’). Cette fonction ne doit pas utiliser de fonctions d’affichage. Testez votre fonction en y faisant plusieurs appels différents dans le main pour vérifier qu’elle fonctionne correctement. Vous pouvez utiliser la fonction afficher_tableau du TD précédent pour afficher la séquence d’ADN, ou bien la fonction print_r (voir page 113), avec une préférence pour la première. Question 3 : Créez une fonction : 1 // $adn : array(string) 2 // -> bool 3 function chercher_T($adn) qui cherche le caractère ’T’ dans l’ADN passé en argument, et renvoie true si elle le trouve, false sinon. Cette fonction ne doit pas utiliser de fonctions d’affichage. 101 Testez votre fonction en y faisant plusieurs appels différents dans le main pour vérifier qu’elle fonctionne correctement. Question 4 : Modifiez la fonction précédente en : 1 // $adn : array(string) 2 // -> bool 3 function chercher_TTT($adn) qui cherche la chaîne ’TTT’ dans l’ADN passé en argument, et renvoie true si elle le trouve, false sinon. Testez votre fonction en y faisant plusieurs appels différents dans le main pour vérifier qu’elle fonctionne correctement. Question 5 : Dans "adn-formulaire.php", créez une fonction : 1 function afficher_formulaire() qui doit afficher un formulaire demandant à l’utilisateur la taille de la séquence à générer (utilisez pour cela un champ texte). Pensez bien à encadrer l’appel à afficher_champ_texte par debut_formulaire et fin_formulaire. Faites un appel à afficher_formulaire dans le main, et vérifiez que le formulaire s’affiche bien lorsque l’on exécute le fichier. Question 6 : Dans le fichier "adn-traitement.php", créez une fonction : 1 function traiter_formulaire() qui doit récupérer la taille entrée par l’utilisateur et l’afficher à l’écran (pour l’instant). Faites appel à cette fonction dans le main et affichez dans le main un lien vers le formulaire avec afficher_lien_interne (voir page 50). Vérifiez que tout fonctionne bien. Question 7 : Modifiez la fonction traiter_formulaire pour afficher une séquence ADN en fonction d’une taille saisie par l’utilisateur dans le formulaire. Affichez aussi si la chaîne ’TTT’ y a été trouvée. 102 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Question 8 : Modifiez la fonction main pour ne traiter les données du formulaire que lorsque l’on est passé au préalable par le formulaire, i.e., si on exécute le fichier "adn-traitement.php" directement, cela ne doit pas générer d’erreur. Question 9 : Sous-séquence quelconque Modifiez vos deux fichiers pour : — demander une sous-séquence de bases azotées à l’utilisateur par un champ texte (en plus de la taille de la séquence à générer), — récupérer cette sous-séquence et l’afficher, — rechercher cette sous-séquence dans la séquence générée (plutôt que de chercher ’TTT’) et afficher le résultat à l’écran. Pour cela vous devrez créer une nouvelle fonction similaire à chercher_TTT mais prenant deux arguments au lieu d’un seul, et qui ne doit (toujours) pas utiliser de fonctions d’affichage, mais doit seulement renvoyer true ou false. L’affichage de ce résultat doit se faire dans traiter_formulaire. Vous pouvez utiliser la fonction str_split (voir page 115) qui convertit une chaîne de caractères en un tableau de caractères. Question 10 : [Bonus] Validation des données Dans le cas où les données saisies par l’utilisateur ne sont pas correctes (par exemple il a entré un nombre négatif, ou une chaîne de caractères qui n’est pas un nombre), vous devez afficher un message d’erreur l’invitant à saisir à nouveau ses données, et donc afficher aussi le formulaire. Si toutes les données sont correctes, le formulaire ne doit pas être affiché. Indication : votre fonction traiter_formulaire devrait maintenant retourner un booléen qui vaut true si les informations saisies sont correctes, ou false sinon. Ce que l’on doit faire ensuite dans le cas false doit alors se trouver en dehors de la fonction traiter_formulaire. Vous pouvez utiliser la fonction is_numeric (voir page 112). Question 11 : [Bonus] Formulaire auto-validé Créer un fichier "auto-form.php" qui contient à la fois le formulaire et le traitement des données. Cela signifie que le formulaire doit envoyer les données au même fichier PHP qui affiche le formulaire. Il faut alors bien faire attention à bien différencier l’affichage du formulaire et le traitement des données, ce qui peut être fait grâce à l’identifiant du formulaire obtenu par get_id_formulaire(). Référez-vous à l’exemple donné en section 2.4.2. 103 Exercice 2 : Compteur Pour effectuer ces exercices, vous devez avoir travaillé les pages 62 à 63 avant de venir en TD. Copiez le code du programme "compteur" (section 2.5) dans le fichier "compteur.php" et testez-le. Question 1 : Modifiez le programme pour que lorsque le compteur atteint 10, on appelle la fonction session_unset(), juste avant l’accolade fermante du main. Exécutez plusieurs fois la page. Quel est l’effet de cette modification ? Exercice 3 : [Bonus] Blackjack Le but de cet exercice est de faire un petit jeu de blackjack simplifié. Les règles sont les suivantes : — Le joueur a un score initial de 0, — À chaque tour, il peut choisir de tirer une carte (un nombre entre 1 et 10), auquel cas la valeur de la carte s’ajoute à son score actuel, — Si son score dépasse 21, le joueur a perdu, — Si son score est exactement 21, il a gagné, — Il peut choisir de “rester” à tout moment, c’est-à-dire arrêter de tirer des cartes, auquel cas la banque tire ses propres cartes (un seul nombre entre 17 et 21 inclus), et si le joueur a un score supérieur à celui de la banque, il gagne, sinon il perd. Le squelette du programme vous est déjà fourni, vous devrez en remplir les trous. Lisez ce qui suit en entier et regardez le programme fourni avant de commencer à répondre aux questions, pour bien avoir une vision globale de ce que vous avez à faire. Question 1 : Affichez les 3 boutons correspondant aux 3 actions possibles : tirer une carte, recommencer la partie, rester et comparer avec la banque. Pour cela, remplissez la fonction afficher_les_boutons. Pour vous aider, on vous fournit déjà la fonction : 1 // $nom : string 2 // $texte : string 3 function afficher_bouton($nom, $texte) qui crée simplement un formulaire vide (contenant donc uniquement le bouton de validation du formulaire). L’argument $nom est la valeur qui sera récupérée par get_id_formulaire() si le bouton est pressé. L’argument $texte est le texte affiché sur le bouton. 104 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Pour le moment, il ne vous est pas demandé d’effectuer les traitements associés à ces boutons/formulaires. Question 2 : Pour pouvoir mémoriser le score du joueur le long de la partie, il faut le stocker dans la session (vous devrez utiliser la clef ’score’). Complétez les fonctions get_score et set_score qui doivent, respectivement, retourner la valeur du score actuel stocké en session, et modifier la valeur du score en session. Par la suite, vous ne devrez plus utiliser directement le tableau $_SESSION[], mais uniquement les deux fonctions get_score et set_score. Question 3 : Complétez la fonction recommencer qui doit remettre le score du joueur à zéro. Complétez le main pour appeler la fonction recommencer lorsque l’on presse le bouton correspondant. Note : La fonction recommencer est déjà appelée dans le programme lorsque la session ne contient aucune entrée ’score’, ce qui aura donc pour effet,une fois la fonction recommencer implémentée, de créer cette clef et d’initialiser le score à 0. Question 4 : Remplissez le corps de la fonction afficher_score, qui doit tout simplement afficher à l’écran le score courant sous la forme : Score actuel : 0 (pour le moment le score est nécessairement 0). Question 5 : Dans le main, récupérez le nom du bouton qui a été pressé (le cas échéant) et, s’il s’agit du bouton tirer, appelez la fonction tirer. Question 6 : Dans la fonction tirer, tirez une carte sous forme d’un nombre aléatoire (fonction rand, cf. section A.1.3) dans une variable (vous en aurez besoin pour la suite), et affichez à l’écran la valeur tirée : Vous avez tiré : 6 Testez votre programme. Il doit donc vous afficher la carte que vous avez tirée (en plus d’afficher le score actuel, toujours de 0 pour le moment). 105 Question 7 : Complétez la fonction tirer pour augmenter le score actuel en fonction de la valeur de la carte tirée. Testez votre programme plusieurs fois avec les boutons tirer et recommencer. Question 8 : Finalement, complétez la fonction rester, le main, ainsi que la fonction tirer pour se conformer aux règles du jeu données plus haut. Affichez notamment les messages correspondant à une victoire ou un échec. Testez votre programme en long, en large, et en travers. 106 CHAPITRE 4. TRAVAUX DIRIGÉS PHP TD 7 : PHP/MySQL Pour effectuer ces exercices, vous devez avoir travaillé les pages 66 à 73 avant de venir en TD. Exercice 1 : Les Simpson Ouvrez le répertoire du TD. Il y a 4 pages PHP, numérotées par ordre d’utilisation. Chaque page doit renvoyer à la suivante et la dernière doit afficher un lien de retour vers la première. — Sur la première page doit être affichée une liste des noms de familles existants (sans doublon) dans la base, parmi lesquels l’utilisateur doit choisir un nom, — La validation de ce formulaire renvoie à "page2.php" qui doit proposer une liste des prénoms possibles pour le nom choisi, ce qui devrait suffire à identifier un personnage de manière unique. — Ce qui renvoie à la page 3, où l’on demande d’écrire un commentaire sur le personnage choisi (nom et prénom). — La validation de ce dernier formulaire renvoie alors à la page 4, où tous les commentaires du personnage sélectionné doivent être affichés dans une liste d’items. Il peut donc y avoir plusieurs commentaires pour un même personnage. Question 1 : Dans PhpMyAdmin, importez la base "simpsons.sql". Question 2 : Dans le fichier "page1.php", complétez la fonction main qui doit, dans l’ordre : 1. établir une connexion à ’localhost’ (nom d’utilisateur : ’root’, mot de passe : ’mysql’ ou ’’ (vide)), 2. sélectionner la base ’simpsons’, 3. fermer la connexion à la base. Testez votre fichier pour vérifier que la connexion se fait bien. Si tout se passe bien, rien ne doit s’afficher. Question 3 : Créez ensuite la fonction : 1 function afficher_noms_famille() 107 qui doit effectuer une requête SELECT en utilisant mysql_query_affiche (voir page 67) et afficher les résultats de la requête, un nom de famille par ligne en utilisant mysql_ligne_suivante (voir page 67) et une boucle while (suivre l’exemple page 68). Appelez la fonction afficher_noms_famille dans le main, juste avant la fermeture de la connexion à la base. Testez votre premier fichier. Question 4 : Transformez l’affichage des noms en une liste déroulante en utilisant debut_select (voir page 55) et fin_select, à l’intérieur d’un formulaire qui doit renvoyer à la page ’page2.php’. Remarque : Les erreurs PHP apparaissant entre debut_select et fin_select ont tendance à être masquées. Ainsi, pour pouvoir afficher les erreurs dues à une requête défectueuse par exemple, il faut placer celle-ci avant debut_select. Question 5 : Complétez le fichier "page2.php". Attention, vous avez ici à créer une requête paramétrée. Il vous faut donc utiliser mysql_real_escape_string (voir page 69) ou bien créer la fonction chaine_en_sql (voir page 72) et l’utiliser. Question 6 : Réalisez les autres pages les unes après les autres. Dans PhpMyAdmin, vous devrez créez la table ‘commentaires‘ avec la structure qui convient. Utilisez le mécanisme des sessions si vous avez besoin de mémoriser des informations à travers plusieurs pages PHP. Question 7 : Veillez à ce que si l’utilisateur exécute une des pages directement (sans passer par un formulaire), il soit redirigé vers "page1.php" (soit avec afficher_lien_interne, soit avec redirection (voir page 62)). Question 8 : [Bonus] Dans le même répertoire, créez un nouveau fichier "tout.php" dans lequel vous devez faire la même chose que ci-dessus, mais dans un seul et unique fichier. Identifiez enfin les morceaux de code qui se ressemblent beaucoup et remplacez-les par des appels à des fonctions que vous définirez, de manière à diminuer au maximum les redondances de code. Choisissez des noms clairs pour vos fonctions et documentez-les (types des arguments et de la valeur de retour, petite phrase d’explication). 108 CHAPITRE 4. TRAVAUX DIRIGÉS PHP TD 8 : [Bonus] Labyrinthe L’objectif de cet exercice est de créer un mini-jeu où l’on doit amener le joueur vers un but à travers un labyrinthe. N’hésitez pas à ajouter des fonctions intermédiaires selon vos besoins ! Et même à modifier votre code après coup pour le rendre plus simple en ajoutant des fonctions. Question 1 : Ouvrez le fichier "labyrinthe.php". Ajoutez-y une fonction main, et récupérez le nom du formulaire (qui se résumera à un bouton) dans la variable $id_formulaire. Question 2 : Une matrice est un tableau PHP où chaque case contient elle-même un tableau PHP. Dans le main, définissez la matrice $mat1 suivante : 1 $mat1 = array( array(’a’, ’b’, ’c’, ’d’), 2 array(’1’, ’2’, ’3’, ’4’), 3 array(’w’, ’x’, ’y’, ’z’) ); Créez une fonction : 1 // $matrice : array(array(string)) 2 function afficher_labyrinthe($matrice) qui prend en argument une matrice et l’affiche à l’écran. Utilisez pour cela les fonctions d’affichage de table PHP (voir les fonctions debut_table et autres). Pour l’argument $nom de debut_table, donnez le nom ’laby’ à la table : ceci permettra d’avoir un affichage automatiquement correctement formaté. Testez dans le main l’affichage de la matrice $mat1. Vérifiez bien que les lignes et les colonnes ne sont pas transposées. Question 3 : Créez une fonction : 1 2 3 4 // $nb_lignes : int // $nb_colonnes : int // -> array(array(string)) function creer_matrice($nb_lignes, $nb_colonnes) qui crée un tableau de $nb_lignes cases, dont chaque case contient elle-même un tableau de $nb_colonnes cases. Chaque case doit contenir le symbole ’X’ (nous le changerons plus tard). Remarque : Vous aurez besoin de 2 boucles imbriquées, ou bien vous pouvez décomposer le problème en faisant d’abord une sous-fonction affichant uniquement une ligne. 109 Dans le main, creer_matrice, et créez une matrice de 10 lignes et 5 colonnes avec la fonction affichez là avec la fonction afficher_labyrinthe. (Vous pouvez maintenant supprimer l’affichage de $mat1.) Question 4 : Modifiez la fonction creer_matrice pour que seules les cases du bord aient la valeur ’X’ (pour un mur), les autres devant avoir la valeur ”. Testez votre fonction. Question 5 : Pour éviter de créer une nouvelle matrice à chaque exécution de la page PHP, il nous faut la sauvegarder dans une session (voir la section 2.5). Dans le main, ajoutez une nouvelle matrice dans la session si aucune n’y existe déjà ; puis récupérez la matrice stockée dans la session pour l’afficher. Exécutez plusieurs fois la page PHP pour vérifier que la matrice n’est bien créée qu’une seule fois (dans le navigateur, appuyez plusieurs fois sur F5 ou rafraîchissez la page). Question 6 : Nous allons maintenant avoir besoin de boutons d’action. Un bouton d’action est simplement un formulaire sans autre champ que le bouton d’envoi des données. Comme nous allons avoir besoin de plusieurs boutons, commencez par créer une fonction : 1 // $nom : string 2 // $texte : string 3 function afficher_bouton($nom, $texte) qui affiche un formulaire de nom $nom et de texte de bouton d’envoi $texte (référez-vous à la documentation de afficher_formulaire si nécessaire). Faites maintenant une fonction : 1 function afficher_les_boutons() qui affiche (pour le moment) un bouton de nom ’recommencer’ et de texte ’Recommencer’. Enfin, dans le main, si $id_bouton a la valeur ’recommencer’, remplacez la matrice stockée en session par une autre matrice nouvellement créée. Dorénavant, si vous cliquez sur le bouton, cela doit afficher une nouvelle matrice, mais si vous rafraîchissez la page, la matrice ne doit pas changer. Question 7 : Nous allons maintenant ajouter un joueur qui pourra se déplacer dans le labyrinthe. Le joueur est défini par sa position (ligne, colonne), qu’il faut sauver dans la session. 110 CHAPITRE 4. TRAVAUX DIRIGÉS PHP Faites les modifications nécessaires dans votre programme pour : — Créer les positions initiales du joueur (par exemple en 1, 1) si elles n’existent pas dans la session et les y sauver, — Modifier l’affichage de la matrice pour afficher le joueur au bon endroit. Le joueur sera représenté par ’O’. Question 8 : Ajoutez un bouton ’Droite’ (de nom ’droite’) dans la fonction afficher_les_boutons. Faites ensuite une fonction : 1 2 3 4 5 // $direction : string // $ligne : int // $colonne : int // $matrice : array(array(string)) function bouger($direction, $ligne, $colonne, $matrice) qui prend en argument une direction (’droite’, ’gauche’, ’haut’ ou ’bas’), la position courante du joueur et la matrice, et qui modifie dans la session la position du joueur en fonction de la direction donnée. Dans un premier temps, ne faites que la direction ’droite’, puis une fois que cela fonctionne, ajoutez les autres directions (et les boutons associés). Vous aurez à modifier certaines autres fonctions, notamment le main. Question 9 : Ajoutez aléatoirement des murs au milieu du labyrinthe. Un clic sur ’Recommencer’ doit remettre le joueur en position initial (1, 1) et modifier la disposition des murs. Question 10 : Modifiez votre programme pour ajouter une case spéciale ’*’ dans la matrice. Lorsque le joueur atteint cette case, affichez un message de victoire. 111 TD 9 : [Bonus] Réseau social Le but de cet exercice est de créer un mini réseau social, où chaque personne inscrite peut voir, ajouter, supprimer des amis, où l’on peut aussi ajouter et supprimer des inscrits. Question 1 : Base de données Commencez par créer la base de données permettant de modéliser le problème. Réfléchissez bien à la modélisation de manière à ce que votre base de données ne contienne aucune redondance d’information. Puis ajoutez quelques enregistrements pour pouvoir tester des requêtes. Question 2 : Commencez par faire une page permettant de voir les amis d’une personne choisie dans un formulaire. Question 3 : Faites ensuite les autres pages permettant de : — Ajouter une nouvelle personne dans la base (un nouvel inscrit), — Ajouter, à une personne inscrite, un ami parmi les personnes inscrites qui ne sont pas encore ses amis, — Supprimer un ami (pas la personne inscrite, mais le lien d’amitié), — Supprimer une personne (ce qui doit entraîner la suppression de tous ses amis !) Veillez à bien gérer les cas particuliers et les erreurs possibles de l’utilisateur (ami inexistant ? Personne non-inscrite ? etc.). Question 4 : Connexion On aimerait maintenant pouvoir se "connecter" au site de manière à ce que toutes les requêtes soient relatives à la personne connectée, sans qu’elle ait besoin d’entrer son nom à chaque fois. Seule la personne connectée peut s’ajouter ou supprimer des amis, ou supprimer son compte. Modifiez votre programme en conséquence. Vous aurez notamment besoin pour cela de mémoriser la personne connectée dans une session. Annexe A PHP : Addendum A.1 Quelques fonctions et structures supplémentaires Il existe de nombreuses fonctions en PHP, et vous pouvez y accéder à partir des URL fournies dans l’annexe C. En voici quelques-unes qui peuvent vous être utiles. A.1.1 Tests de types Pour tester le type d’une valeur (ou donc d’une variable), il existe un certain nombre de fonctions PHP : 1 // $valeur : any 2 // -> bool 3 function is_int($valeur) 1 // $valeur : any 2 // -> bool 3 function is_float($valeur) 1 // $valeur : any 2 // -> bool 3 function is_numeric($valeur) 1 // $valeur : any 2 // -> bool 3 function is_string($valeur) 1 // $valeur : any 2 // -> bool 3 function is_bool($valeur) 112 A.1. QUELQUES FONCTIONS ET STRUCTURES SUPPLÉMENTAIRES 113 1 // $valeur : any 2 // -> bool 3 function is_array($valeur) Par exemple, is_int(5.) retourne false, comme is_float(5), mais is_int(5) retourne true, comme is_bool(3 < 0) et is_string(’une ’. ’chaîne’). À noter que is_numeric teste si la valeur est un nombre ou une chaîne de caractères contenant un nombre. Ainsi, is_numeric(’5’) retourne true, mais is_int(’5’) retourne false. A.1.2 print_r La fonction : 1 // $mon_tableau : array 2 function print_r($mon_tableau) permet d’afficher à l’écran le contenu du tableau passé en argument. En effet : 1 $tableau = array(’oui’, ’non’, ’peut-être’); 2 printline($tableau); afficherait uniquement : Array ce qui n’est pas très informatif... Alors que : 1 $tableau = array(’oui’, ’non’, ’peut-être’); 2 print_r($tableau); affiche : Array ( [0] => oui [1] => non [2] => peut-être ) La fonction SI_print_r est similaire à print_r mais avec un affichage plus élégant. A.1.3 rand La fonction : 1 2 3 4 // $min : int // $max : int // -> int function rand($min, $max) retourne un nombre entier tiré aléatoirement et uniformément entre les valeurs $min et $max incluses. Exemple : 114 1 2 3 4 ANNEXE A. PHP : ADDENDUM $n = rand(0, 100); // valeur aléatoire entre 0 et 100 compris printline($n); // affichage de cette valeur $n = rand(0, 100); // tirage d’une nouvelle valeur aléatoire printline($n); // affichage de la nouvelle valeur A.1.4 include L’instruction include(’mon-fichier.php’); permet d’insérer à l’endroit courant dans le fichier courant le contenu du fichier "mon-fichier.php". Ceci est très pratique, notamment si l’on écrit des fonctions qui peuvent servir dans plusieurs fichiers. A.1.5 break L’instruction break; permet de terminer prématurément l’exécution d’une boucle. Elle ne peut exister qu’à l’intérieur d’une boucle. A.1.6 isset La fonction : 1 // $x : var 2 // -> bool 3 function isset($x) renvoie true si la variable $x possède une valeur. A.1.7 array_key_exists La fonction : 1 2 3 4 // $clef : string // $tableau : array // -> bool function array_key_exists($clef, $tableau) renvoie true si la clef $clef existe dans le tableau $tableau. A.1.8 unset La fonction : 1 // $x : var 2 function unset($x) permet de supprimer la variable $x, de sorte que isset($x) retourne false. A.2. CHAÎNES DE CARACTÈRES A.1.9 115 str_split La fonction : 1 // $str : string 2 // -> array(string) 3 function str_split($str) transforme la chaîne de caractères $str en un tableau de caractères. Exemple : 1 SI_print_r(str_split(’abcd’)); affiche : Array ( [0] [1] [2] [3] ) A.2 => => => => a b c d Chaînes de caractères Une chaîne de caractères est une suite de symboles qui sera interprétée par le programme comme du texte et non comme des commandes. Par exemple : 1 $texte = ’printline("Bonjour !");’; ne fera que donner la valeur ’printline("Bonjour !");’ à la variable $texte et n’écrira pas à l’écran "Bonjour !". Si par la suite on fait printline($texte);, on affichera à l’écran : printline("Bonjour !"); A.2.1 Guillemets simples et doubles, échappement de guillemet Les guillemets doubles sont identiques aux guillemets simples à la différence qu’ils permettent de transformer les variables (et uniquement les variables simples, pas les indices dans les tableaux comme $_SESSION[’prenom’]) en leur valeur. Par exemple : 1 printline("la valeur de x est $x."); est équivalent à : 1 printline(’la valeur de x est ’ . $x . ’.’); ce qui peut être très pratique dans la majorité des cas, mais nécessite parfois de faire attention à quelques pièges. 116 ANNEXE A. PHP : ADDENDUM Pour afficher une apostrophe dans des guillemets simples, on la précède du symbole "\". On appelle cela de la déspécialisation (car l’apostrophe a un rôle spécial dans une chaine entre guillemets simples, rôle qu’on lui ôte ainsi) : 1 ’Quelqu\’un a dit un jour : "À l\’origine de toute erreur attribuée à l \’ordinateur, vous trouverez au moins deux erreurs humaines. Dont celle consistant à attribuer l\’erreur à l\’ordinateur"’ Idem dans une chaîne de caractères entre guillemets doubles : 1 "Dave Small a dit : \"Un langage de programmation est une convention pour donner des ordres à un ordinateur. Ce n’est pas censé être obscur, bizarre et plein de pièges subtils. Ca, ce sont les caracté ristiques de la magie.\"" Il n’y a pas besoin de déspécialiser les guillemets simples dans une chaîne de caractères entre guillemets doubles et vice et versa. A.3 Variables globales Bien qu’il soit recommandé d’utiliser le minimum de variables globales possibles et d’utiliser au maximum le passage de valeur en argument des fonctions, il reste possible d’utiliser des variables globales, c’est-à-dire qu’elles conserve leur valeur au travers des différentes fonctions (mais au contraire des sessions, elles perdent leur valeur à la prochaine exécution du fichier). En fait, toute variable peut être utilisée de manière globale. Il faut pour cela déclarer cette variable comme globale dans toute fonction l’utilisant : 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?php function test_global() { global $x, $y; $y = 10; printline($x); } function main() { global $x, $y; $y = 3; $x = 5; test_global(); printline($y); } ?> Ce programme affichera bien 5 et 10, alors que sans le mot clef global, PHP aurait d’abord affiché une erreur : Notice: Undefined variable: x in test.php on line 6 pour signaler que la variable $x n’est pas définie, puis il affiche la valeur initiale de $y, A.4. GESTION DES ERREURS 117 c’est-à-dire 3. Remarque : Plus que toute autre, une variable globale doit avoir un nom clair. Il existe des variables particulières, dites super globales, comme les tableaux du type $_SESSION[], qui restent globaux par défaut, sans avoir besoin de préciser global. La non-globalité est le comportement par défaut depuis la version 4.2.0 de PHP. Cependant, ceci peut varier selon la configuration et la version des serveurs Apache sur lequel est exécuté le programme PHP. A.4 Gestion des erreurs L’erreur la plus courante que vous verrez sera probablement : Parse error: parse error, expecting ‘’,’’ or ‘’;’’ in c:\\mon_repertoire\\monfichier.php on line 6 Petite explication : Parse error: signifie que PHP a détecté une erreur au moment de la lecture de votre fichier, expecting ‘’,’’ or ‘’;’’ signifie qu’il manque une virgule ou un point-virgule, in c:\\mon_repertoire\\monfichier.php dans le fichier "monfichier.php", on line 6 au moment où PHP a atteint la ligne 6. Cela signifie que l’erreur se trouve sur la dernière instruction précédant la ligne 6. Il suffit probablement d’ajouter un point-virgule à la fin de l’instruction précédente pour résoudre l’erreur. Une autre erreur fréquente est celle-ci : Parse error: syntax error, unexpected $end in monfichier.php on line 23 qui signifie que PHP a atteint prématurément la fin du fichier pendant qu’il le lisait. En général, ceci est dû à une accolade fermante manquante quelque part dans le fichier (la ligne 23 étant ici la dernière ligne du fichier). Annexe B Indentation en PHP L’indentation est le fait de décaler les lignes de plusieurs espaces vers la droite pour rendre le programme plus lisible. On parle aussi de tabuler une ligne, c’est-à-dire le fait de la décaler vers la droite d’une tabulation, un appui sur la touche "tabulation" (la touche avec deux flèches sur la gauche du clavier). Imaginez un roman où tous les mots seraient collés les uns aux autres. Cela donnerait la même difficulté de lecture qu’un programme non indenté. Voici un exemple de code non indenté : 1 2 3 4 5 6 7 8 9 10 11 if($x===’a’) { $sortie = ’b’; if($y===’c’) { print(’d’); } else { $z = ’e’; } } else { print(’f’); $sortie = ’g’; } Ce qui est très peu lisible, et encore ce n’est qu’un petit programme. Voici le code précédent indenté : 1 if($x===’a’) { 2 $sortie = ’b’; 3 if($y===’c’) { 4 print(’d’); 5 } else { 6 $z = ’e’; 7 } 8 } else { 9 print(’f’); 10 $sortie = ’g’; 11 } Ici, chaque accolade ouvrante se trouve en fin de ligne (donc passer une ligne après cha118 119 cune), et chaque accolade fermante correspondante se trouve juste sous le premier symbole de la ligne où se trouve l’accolade ouvrante, de sorte que l’on puisse savoir, d’un rapide coup d’œil, quelles sont les instructions qui appartiennent au même bloc d’instructions. Le sens du programme apparaît alors beaucoup plus nettement. Moins d’efforts sont nécessaires pour le comprendre. Certaines erreurs sont aussi très faciles à repérer avec une bonne indentation, et beaucoup plus difficile sans indentation (attention à l’arrachage de cheveux !). Dans de nombreux éditeurs de textes, tel Notepad++, il est possible de sélectionner plusieurs lignes à la fois (soit à la souris, soit avec la touche Shift appuyée et les flèches directionnelles) et d’appuyer sur (Shift-) "tabulation" pour les décaler d’une tabulation vers la droite (gauche). Il ne faut pas non plus hésiter à sauter une ligne entre des groupes d’instructions différents pour rendre la lecture du programme plus facile. Et surtout : mettre des commentaires tout au long du programme pour expliquer ce qu’il fait ! À l’intérieur d’une paire d’accolades toutes les lignes doivent être décalées d’un cran supplémentaire vers la droite (tabulation) par rapport à la ligne des accolades. Annexe C Ressources et aide en ligne Il existe de très nombreuses ressources sur PHP, HTML, CSS, MySQL. Une simple recherche Google vous donnera dans les premiers résultats des pointeurs souvent pertinents. Si vous connaissez le nom d’une fonction PHP mais que vous ne savez pas comment l’utiliser, le mieux est de faire une recherche Google du genre "php strpos" si vous cherchez de l’aide sur la fonction "strpos". Vous aurez tout ce dont vous avez besoin dès les premiers résultats. Apprenez à être autonome ! Apprenez à utiliser par vous-même les moteurs de recherche, ce sont de puissants outils, et pas uniquement pour la programmation, mais dans tout domaine 1 . Le site officiel français du PHP est : http://fr2.php.net/manual/fr/ Il est parfaitement complet, en français et didactique. Veuillez vous y référer pour tout information complémentaire sur PHP. Voici quelques tutoriels en français de PHP en ligne : — Commentcamarche : http://www.commentcamarche.net/contents/ php/phpintro.php3 — Site du Zéro : http://www.siteduzero.com/tutoriel-3-14668-unsite-dynamique-avec-php.html — Manuels PHP : http://www.manuelphp.com/manuels 1. Attention toutefois à bien vérifier vos sources et à les croiser si besoin. Google et Wikipedia sont loin d’être infaillibles ! 120 Annexe D Utiliser Notepad++, PHP et MySQL chez vous Cette annexe a pour but de vous permettre d’utiliser chez vous les outils du cours. D.1 Éditeur de texte : Notepad++ Tout éditeur de texte (y compris le Bloc Notes de Windows, bien qu’il soit peu pratique) peut être utilisé pour écrire du HTML ou du PHP. Notepad++ est un éditeur de texte plus pratique et possédant de nombreuses fonctionnalités. Il fournit entre autres la coloration syntaxique (les mots clefs sont en couleurs). Vous pouvez le télécharger à : http://notepad-plus-plus.org/fr/ D.2 Navigateur : Firefox Il vous faut un navigateur pour obtenir un rendu visuel du code HTML et pour faire l’interface avec le serveur Apache. Tout bon navigateur fera l’affaire (par exemple Internet Explorer, Chrome, ou Firefox, avec une préférence pour ce dernier pour ses fonctionnalités et la qualité de son rendu). D.3 Serveur Apache/Base de données : EasyPHP Pour le serveur Apache, qui sert à transformer les pages PHP en fichiers HTML et faire le lien avec le navigateur (donc à exécuter les fichiers PHP), ainsi que pour la liaison avec une base de données, il est recommandé d’utiliser EasyPHP, qui intègre tous ces outils. 121 122 ANNEXE D. UTILISER NOTEPAD++, PHP ET MYSQL CHEZ VOUS Vous pouvez le télécharger à : http://www.easyphp.org/ XAMPP est un logiciel similaire à EasyPHP qui peut être installé pour Windows, Linux ou Macintosh : http://www.apachefriends.org/fr/xampp.html D.3.1 Configuration d’EasyPHP Pour utiliser correctement EasyPHP comme dans l’environnement de travail de cours, vous devez d’abord créer un répertoire de travail, disons par exemple "www" dans le répertoire "Documents", ce qui donne pour Windows : C :\Users\moi\Documents\www. Vous pouvez alors y créer la même arborescence des répertoires qu’en cours : Documents www BD ... Lancez ensuite EasyPHP. Tout en bas à droite de Windows, à côté de l’horloge, vous devez avoir un petit "e" pour EasyPHP. Cliquez dessus avec le bouton droit de la souris. Un menu apparait, choisissez "Administration". Ceci doit ouvrir une fenêtre dans votre navigateur Web. Dans la rubrique "Apache", sous-rubrique "Alias", cliquez sur "ajouter". Dans le champ 2, écrivez "www" (sans les guillemets). Dans le champ 3, entrez le chemin d’accès complet au répertoire "www" que vous avez créé, par exemple C :\Users\moi\Documents\www pour Windows. Cliquez sur OK. Maintenant, tant que EasyPHP est lancé, vous pouvez utiliser votre ordinateur de la même manière qu’en cours. D.4 Paquetage AgroSIXPack Téléchargez AgroSIXPack soit à l’adresse : http://gaia.agroparistech.fr/~orseau si vous êtes sur le réseau intranet d’AgroParisTech (c’est-à-dire dans les salles ou dans les chambres de Grignon, ou sur le site de Claude Bernard), ou bien à l’adresse : https://gaia.agroparistech.fr/~orseau sinon (notez le "s" à "https"), mais il vous faudra vous identifier au préalable pour avoir accès à la page. Puis : D.4. PAQUETAGE AGROSIXPACK 123 — Sous Windows, téléchargez l’installeur AgroSIXPack.exe, exécutez-le et choisissez le répertoire d’installation de l’alias que vous avez créé pour EasyPHP, soit C :\Users\moi\Documents\www. — Sous MacOS X et sous Linux, téléchargez l’archive AgroSIXPack.zip et décompressezlà dans le répertoire de l’alias créé pour l’équivalent d’EasyPHP, que nous avons nommé plus haut C :\Users\moi\Documents\www. Vous devez maintenant avoir l’arborescence suivante : Documents www BD ... PHP TD1 TD2 ... Hormis pour "Documents", vous devez avoir exactement cette arborescence, sinon cela risque de ne pas fonctionner. Vous pouvez maintenant ouvrir le fichier AgroSIXPack.php à travers le serveur PHP, ce qui nécessite que EasyPHP ou équivalent soit démarré, à l’adresse : http://localhost/www/PHP/AgroSIXPack.php (selon de votre configuration). Vos fichiers PHP doivent nécessairement se trouver dans un sous-répertoire du répertoire contenant le fichier AgroSIXPack.php. Index PHP Affichage SI_print_r, 90, 113, 115 afficher_champ_paragraphe, 53, 56 afficher_champ_password, 53 afficher_champ_texte, 53, 56, 58, 60, 61, 70, 97, 101 afficher_checkbox_item, 54– 56 afficher_checkbox, 53, 54, 56, 98 afficher_hrule, 48 afficher_image, 50 afficher_lien_externe, 50, 51 afficher_lien_interne, 50, 51, 63, 99, 101, 107 afficher_liste_item, 48, 71 afficher_radio_item, 55, 56 afficher_select_item, 55, 56, 73 afficher_table_donnee, 49, 50, 95 afficher_table_entete, 49 afficher_table_ligne, 49, 90 afficher_titre, 47, 64 ajouter_champ_cache, 55 bold, 48 debut_formulaire, 52, 56, 58, 59, 61, 70, 96, 97, 101 debut_groupe_checkbox, 54, 56, 98 debut_groupe_radio, 54, 56 debut_liste, 48, 71 debut_select, 55, 56, 73, 98, 107 124 debut_table_ligne, 49, 50, 95 debut_table, 48–50, 95, 108 debut, 64 emph, 48 fin_formulaire, 52, 56, 58, 61, 70, 96, 97, 101 fin_groupe_checkbox, 54, 56 fin_groupe_radio, 55, 56 fin_liste, 48, 71 fin_select, 55, 56, 73, 107 fin_table_ligne, 49, 50, 95 fin_table, 49, 50, 95 fin, 64 infos_expr, 12, 14, 75 lien_externe, 51 lien_interne, 51 newline, 33, 47, 87 print_r, 90, 100, 113 printline, 8–11, 13–33, 35, 37– 39, 41, 43–45, 47, 48, 59–61, 63, 64, 68, 69, 75–77, 81–85, 87, 88, 90–93, 96, 97, 113–116 print, 37–39, 41, 47, 87, 90, 118 Général and, 12 array_key_exists, 60, 62, 63, 114 array, 10, 42–45, 49–51, 60, 90– 93, 108, 113 break, 114 count, 43, 92 do, 39, 40 elseif, 21 else, 20–22, 32, 59, 63, 79, 80, 118 false, 10–12, 19, 20, 22, 32, 38, INDEX 53–55, 58–62, 68, 69, 77, 98, 100– 102, 113, 114 floatval, 13, 14, 76 foreach, 43–45, 60, 90 for, 40, 41, 43, 88–90 function, 8, 9, 17, 23–36, 39, 47– 56, 58–62, 64, 66–72, 82, 83, 87– 98, 100, 101, 103, 106, 108–110, 112–116 get_id_formulaire, 59, 61, 72, 98, 102, 103 global, 116, 117 if, 19–22, 32, 37, 39, 58–61, 63, 68, 72, 79, 80, 89, 118 include, 36, 73, 114 intval, 13, 16, 76 is_array, 113 is_bool, 112, 113 is_float, 112, 113 is_int, 112, 113 is_numeric, 102, 112, 113 is_string, 112, 113 isset, 114 main, 8–10, 17, 23–30, 32, 34, 35, 39, 46, 56, 58, 59, 61, 62, 64, 70, 71, 81–84, 86, 87, 90–93, 96–98, 100–110, 116 or, 12 rand, 78, 91, 104, 113, 114 redirection, 62, 107 return, 30–35, 72, 87 session_unset, 63, 103 str_split, 102, 115 strval, 13, 14, 76 true, 10–12, 19, 20, 22, 32, 38, 56, 58, 60, 68, 69, 77, 100–102, 113, 114 unset, 63, 114 valeur_champ, 52, 58–61, 71, 97, 98 valeur_checkbox, 60, 84, 98 while, 37–41, 43, 58, 68, 69, 71, 73, 86, 88–90, 107 125 MySQL mysql_close, 66, 70, 71 mysql_connect, 66, 71 mysql_fetch_assoc, 68 mysql_ligne_suivante, 66, 68, 69, 71, 73, 107 mysql_query_affiche, 66–73, 107 mysql_query_debug, 67, 68 mysql_query, 67, 68 mysql_real_escape_string, 69– 73, 107 mysql_select_db, 66, 71 Operateurs Opérateurs d’affectation, 17 Opérateurs de comparaison, 10 Opérateurs logiques, 12