PHP & bases de données Problématique PLAN Solutions sans base de données Avantages / Inconvénients Serveur HTTP et serveur BdD Exemple de mysql Base de données mysql API PHP Exemples CG 2009 1 Problématique On veut disposer d'un site dont le contenu soit géré automatiquement : ajouter un élément (article de catalogue, abonné, nouvelle etc) ne nécessite : * ni modification des programmes * ni modification des pages HTML existantes mais simplement, ajouter une donnée, soit dans un fichier, soit dans une ou plusieurs tables d'une base de données. Ainsi, le concepteur ne voit plus le site au premier degré, mais englobe dans sa conception l'administration et l'utilisation. Il y a séparation des rôles : 1 Programmeur 2 Webmestre 3 Utilisateur CG 2009 2
Solution sans base de données / Une solution sans base de donnée sous-entend qu'il n'y a pas de connexion à un serveur de base de données, mais qu'il n'y a pas non plus de gestion de base de données propriétaire (codée dans des fichiers de données formatés). Exemple en utilisant une arborescence (TP) menu_1 menu_2 menu_3 images lien.txt index.html lien.txt index.html lien.txt index.html poireau.jpg cerise.jpg cochon.jpg Un site est généré à partir d'une arborescence : * le menu de la page d'accuei reflète la liste des répertoires menu_i * les messages et/ou images utilisés pour créer les menus figurent dans un fichier formaté lien.txt placé dans le répertoire associé. * les cibles des liens du menu sont les différents fichiers index.html CG 2009 3 Solution sans base de données Fichier menu_1/lien.txt Promo sur le poireau!!! poireau.jpg CG 2009 4
Solution sans base de données function hpage(){ echo "<center>le spécialiste du poireau...<hr />"; if ($dir = @opendir(".")) { // ouverture du dossier while($file = readdir($dir)) { // lecture d une entrée // affichage du nom de fichier, seulement les répertoires if (is_dir($file) && substr($file, 0, 5)=="menu_" ) { //ouverture de menu_x/lien.txt x=[1,2,3,...] $f = fopen("$file/lien.txt","r"); $label = fgets($f); $label = fgets($f); fclose($f); $num = substr($file, 5); // on garde la fin de la chaîne echo "\t<a href=\"index.php?page=$num\"> <img src=\"images/$label\" height=\"100\"/> </a>\n"; closedir($dir); // fermeture du dossier echo "</center>"; Exemple: affichage du menu «icônes» CG 2009 5 Solution sans base de données Avantages : Simplicité de mise en oeuvre. Efficace. Maintenance des pages aisée Temps d'accès rapide Inconvénients Lorsque le nombre de fonctions augmente, les fichiers de configuration peuvent devenir un peu compliqués Séparation programme/contenu pas forcément très claire CG 2009 6
PHP & bases de données Principe La base de données contient les paramètres et le contenu du site Les scripts php présentent les pages en fonction du contenu de la base de données Les informations collectées par l'intermédiaire de formulaires sont également insérées dans des tables Avantage Il y a une séparation entre le «moteur» constitué de programmes et les données (articles, utilisateurs, catalogue...) Sauvegarder le site <=> sauvegarder la base de données L'accès aux informations est possible par des outils extérieur au site Inconvénient Il faut deux serveurs (HTTP + BDD) => temps d'accès croissant CG 2009 7 PHP & bases de données USE mysql; CREATE USER 'claude'@'%'; Configuration préliminaire de la base de données GRANT USAGE ON *. * TO 'claude'@'%' WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0 ; CREATE DATABASE IF NOT EXISTS `claude` ; GRANT ALL PRIVILEGES ON `claude`. * TO 'claude'@'%'; UPDATE USER SET password=password('mdp') where user='claude'; Un utilisateur est créé avec une base de données qui porte son nom. L'utilisateur peut accéder à sa base à partir de toutes les machines du réseau. CG 2009 8
Technologie PHP & bases de données Prog. PHP API Serveur HTTP Requètes HTTP clients Pilote Requètes SQL Serveur BdD Un client lance une requète HTTP La requète provoque l'exécution d'un script PHP Le script PHP réalise la connexion avec le serveur de BdB En utilisant les fonctions de l'api, le script exécute des requètes SQL grâce au pilote. CG 2009 9 L'API mysql Il est constitué d'une ciquantaine de fonctions toutes préfixées par mysql_ Exemple: mysql_connect() o mysql_close Ferme la connexion MySQL o mysql_connect Ouvre une connexion à un serveur MySQL o mysql_create_db Crée une base de données MySQL o mysql_drop_db Efface une base de données MySQL o mysql_errno Retourne le numéro d'erreur de la dernière commande MySQL o mysql_error Retourne le texte associé avec l'erreur o mysql_fetch_array Retourne une ligne de résultat sous la forme d'un tableau o mysql_fetch_row Retourne une ligne de résultat sous la forme d'un tableau o mysql_free_result Libère le résultat de la mémoire o mysql_list_fields Liste les champs d'une table MySQL o mysql_list_tables Liste les tables d'une base de données MySQL o mysql_num_fields Retourne le nombre de champs d'un résultat MySQL o mysql_num_rows Retourne le nombre de lignes d'un résultat MySQL o mysql_query Envoie une requête à un serveur MySQL o mysql_result Retourne un champ d'un résultat MySQL o mysql_select_db Sélectionne une base de données MySQL Quelques fonctions importantes... CG 2009 10
<?php Connexion + sélection BdD $link = mysql_connect('localhost', 'claude', 'mdp'); if (!$link) { die('impossible de se connecter : '. mysql_error()); // sélection de la base 'mabase' $db = mysql_select_db('claude', $link); if (!$db) { die ('Impossible de sélectionner la base de données : '. mysql_error());... // opérations de lecture modification écriture mysql_close($link);?> CG 2009 11 Accès à des tables existantes La table 'mesures' est composée de 4 champs. Il y a deux enregistrements. CG 2009 12
Accès à des tables existantes $requete = "select * from mesures"; $resultat = mysql_query($requete); if (!$resultat) { echo "Impossible d'exécuter la requête ($requete) dans la base : ". mysql_error(); exit; else if (mysql_num_rows($resultat) == 0) { echo "Aucune ligne trouvée, rien à afficher."; exit; else { echo "<ul>"; while ($row = mysql_fetch_assoc($resultat)) { // lecture séquentielle echo "<li>".$row["id"]." : ".$row["label"]." = ". $row["valeur"]." (".$row["temps"].")"; echo "</ul>"; mysql_free_result($resultat); CG 2009 13 Accès à des tables existantes Bilan Il faut concevoir la requète SQL (chaîne de caractères) Exécuter la requète avec mysql_query() Interpréter le retour de la fonction (traitement d'erreur : mysql_error() ) Les données lues sont accessibles séquentiellement : $row = mysql_fetch_assoc(..) L'accés est possible en utilisant directement les noms des champs ($row["id"]) CG 2009 14
Modification de données $requete = "update mesures set valeur=10 where id=2"; $resultat = mysql_query($requete); if (!$resultat) { echo "Impossible d'exécuter la requête ($requete): ". mysql_error(); exit; Modification d'un champ existant CG 2009 15 Ajout de données $d = getdate(); $date = $d["year"]."-".$d["mon"]."-".$d["mday"]." ".$d["hours"].":".$d["minutes"].":".$d["seconds"]; echo "Date = $date<br />"; $requete = "insert into mesures(valeur, label, temps) ". " values(25, 'temperature','".$date."')"; echo "Requète : $requete<br />"; $resultat = mysql_query($requete); if (!$resultat) { echo "Impossible d'exécuter la requête ($requete) ". mysql_error(); exit; Ici, la requète construite en PHP dépend du contexte (date et heure) CG 2009 16
Modification/ajout de données CG 2009 17 Application (1) On souhaite créer une page qui présente un formulaire de saisie d'une nouvelle mesures Lorsque le formulaire est validé, la nouvelle mesure est insérée dans la table 'mesures' CG 2009 18
Application (1) <?php if (!isset($_post["valeur"])){ // 1er appel?> <center><h1>ajout d'information</h1> <form action="ajout.php" method="post"> Label : <input type="text" value="" name="label" /> <br /> Valeur: <input type="text" value="" name="valeur"/> <br /> <input type="submit" value="ajouter" /> <br /> </form> </center> <?php else { // validation $link = @mysql_connect('localhost', 'claude', 'mdp'); $db = mysql_select_db('claude', $link); $d = getdate(); $date = $d["year"]."-".$d["mon"]."-".$d["mday"]." ".$d["hours"].":".$d["minutes"].":".$d["seconds"]; $requete = "insert into mesures(valeur, label, temps) ". " values('".$_post["valeur"]."', '".$_POST["label"]. "','".$date."')"; echo "Requète : $requete<br />"; $resultat = mysql_query($requete); mysql_close($link);?> CG 2009 19 Application (1) Validation CG 2009 20
Application (2) Un formulaire permet de visualiser et de modifier les données de la table mesures CG 2009 21 Application (2) echo "<ul><form action='validformmesures.php' method='post'>"; while ($row = mysql_fetch_assoc($resultat)) { echo "<li>".$row["id"]." : ". "Label:<input type='text' value=\"".$row["label"]."\" /> ". "Valeur:<input type='text' value=\"".$row["valeur"]."\" /> "; echo "<input type=\"submit\" value=\"valider\" />"; echo "</form></ul>"; CG 2009 22
Améliorations Application (2) Supprimer un champ (checkbox?) Ordonner les champs par date, ou valeur ou nom Champ 'temps' Reste à faire Le programme traiteformmesures.php CG 2009 23