Cours PHP-MySQL

Partie 2 : Interactions entre PHP et MySQL

Matthias Meusburger
www.meusburger.net/matthias


Sommaire :

  1. Rappels sur les bases de données
    1. Le langage SQL
    2. Les requêtes de type SELECT
    3. Les requêtes de type INSERT
    4. Les requêtes de type UPDATE
    5. Les requêtes de type DELETE

  2. Se connecter au serveur de bases de données
    1. La fonction mysql_connect()
    2. La fonction mysql_pconnect()
    3. La fonction mysql_close()
    4. Exemple

  3. Interroger une base de données
    1. Sélectionner une base de données
    2. Soumettre une requête à une base de données
    3. Résultat de la soumission d'une requête

  4. Exploiter les résultats d'une requête de type SELECT
    1. Connaître le nombre de lignes et de colonnes du résultat
    2. La fonction mysql_fetch_array()
    3. La fonction mysql_fetch_row()
    4. Exemple

  5. Utiliser les requêtes de type INSERT, UPDATE, DELETE
    1. Les formulaires
    2. Utiliser les valeurs récupérées
    3. Exemple

  6. Remarques, Trucs et astuces
    1. Masquer les messages d'erreurs
    2. Simplicité... or die()
    3. Informations sur les champs
    4. Les clés étrangères
    5. Autres fonctions utiles

 

  1. Rappels sur les bases de données :

    PHP tire sa puissance de sa capacité à s'interfacer avec de nombreuses bases de données, dont MySQL.
    MySQL est un système de gestion de bases de données relativement puissant, et qui fonctionne aussi bien sous Linux que sous Windows.
    Avant de commencer à expliquer l'utilisation de MySQL au sein de PHP, il convient de rappeler brièvement quelques notions concernant les bases de données.

    1. Le langage SQL

      Le langage SQL (Structured Query Language) est le langage le plus courant pour communiquer avec une base de données. C'est le langage utilisé pour communiquer avec MySQL. On peut, par son intermédiaire, effectuer diverses opérations sur un serveur de bases de données, aussi bien concernant la structure (créer une base de données, une table, un champ, en modifier la structure, les supprimer...) que concernant les données (sélectionner des données, en ajouter, en effacer, en modifier...). Nous allons ici nous intéresser uniquement aux données elles-mêmes. Voici quelques types de requêtes les concernant.


    2. Les requêtes de type SELECT

      Elles servent à récupérer des données suivant des critères précisés dans la requête.
      Le résultat d'une telle requête est un jeu d'enregistrements, c'est à dire un tableau de zéro, une ou plusieurs lignes et d'une ou plusieurs colonnes.
      Une ligne d'un tel tableau s'appelle un enregistrement.
      Exemple :

      SELECT identifiant, nom, prenom FROM clients WHERE identifiant > 10

      Va pouvoir renvoyer un tableau de ce type :

      identifiant nom prenom
      12 Meusburger Matthias
      13 Cape Joey
      15 De La Rocha Zack
      17 Manson Marilyn
      18 Hepburn Audrey

      On a sélectionné toutes les valeurs des identifiants, noms et prénoms contenus dans la table clients dont la valeur de l'identifiant est supérieure à 10.


    3. Les requêtes de type INSERT

      Elles servent à insérer un nouvel enregistrement dans une table.
      Exemple :

      INSERT INTO clients VALUES (19, 'Einstein', 'Albert);

      On insère un nouvel enregistrement avec pour valeurs : identifiant = 19, nom = Einstein, et prénom = Albert.


    4. Les requêtes de type UPDATE
      Elles servent à modifier un ou plusieurs enregistrements existants.
      Exemple :

      UPDATE clients SET prenom='Cedric' WHERE identifiant=12

      On modifie la ligne de la table clients où l'identifiant est égal à 12 pour remplacer la valeur actuelle du champ prénom par la valeur Cedric.


    5. Les requêtes de type DELETE
      Elles servent à effacer un ou plusieurs enregistrements existants.
      Exemple :

      DELETE FROM clients WHERE identifiant > 15

      On supprime de la table client tous les enregistrements dont la valeur du champ identifiant est supérieure à 15.


    Bien évidemment, il existe d'autres types de requêtes, et la syntaxe des types de requêtes présentés ici sont incroyablement plus riche que dans les exemples donnés. C'est pourquoi, pour des informations exhaustives, il convient de se référer à la documentation de MySQL.




  2. Se connecter au serveur de base de données :

    Deux fonctions existent pour se connecter à une base de données MySQL.

    1. la fonction mysql_connect()

      Prototype : mysql_connect([serveur [, utilisateur[, mot de passe]]])

      Cette fonction fournit une connexion au serveur de base de données précisée en paramètre. La connexion se ferme à la fin de l'exécution du script courant. Il s'agit d'une connexion non persistante.
      La fonction renvoie un identifiant de connexion si la connexion s'est bien passée et FALSE sinon.


    2. la fonction mysql_pconnect()

      Prototype : mysql_pconnect([serveur [, utilisateur[, mot de passe]]])

      Cette fonction marche de la même manière que mysql_connect(), sauf que la connexion ne se termine pas en fin de script, mais est conservée pour un futur accès. Il s'agit d'une connexion persistante.
      La fonction renvoie un identifiant de connexion si la connexion s'est bien passée et FALSE sinon.


    3. la fonction mysql_close()

      Prototype : mysql_close([identifiant de connexion])

      Cette fonction ferme la connexion précisée en paramètre ou la dernière connexion ouverte si rien n'est précisé.
      La fonction renvoie TRUE en cas de succès et false sinon.

    4. Exemple :

      $connect_result = mysql_connect($hostname, $username, $password);
      if (!$connect_result) {
      echo("Impossible de se connecter au serveur de bases de données.\n");
      } else {
      echo("Connexion réussie!\n");
      // Traitements mysql_close($connect_result);
      }

  3. Interroger une base de données

    La plupart des fonctions que nous allons voir maintenant prennent comme paramètre optionnel l'identifiant de connexion que nous avons obtenu avec mysql_connect ou mysql_pconnect. Cependant, si on ouvre qu'une seule connexion à la fois, comme c'est souvent le cas, on pourra se passer de préciser l'identifiant aux fonctions utilisées, dans la mesure où la dernière connexion en date est celle choisie par défaut.

    1. Sélectionner une base de données :

      Une fois connecté au serveur, vous n'utilisez aucune base en particulier. Avant toute chose, il convient donc de sélectionner la base sur laquelle vous allez travailler, grâce à la fonction mysql_select_db

      $nomdelabase = "mabase"; $select_result = mysql_select_db($nomdelabase);
      if (!$select_result) { echo("Impossible de se connecter à la base de données $nomdelabase"); } else { echo("Connecté à la base $nomdelabase !"); // Traitements }

    2. Soumettre une requête à la base de données :

      La fonction mysql_query() permet d'envoyer une requête SQL à la base de données.

      /* On suppose que la connexion au serveur ainsi que la sélection de la base de données ont déjà été faites */ $query = "SELECT * FROM matable WHERE monidentifiant > 10";
      $query_result = mysql_query($query);
      if (!$query_result) { echo ("Impossible d'afficher les résultats"); } else { echo ("Voici les résultats"); // Traitements }

    3. Résultat de la soumission d'une requête :

      Le comportement de la fonction mysql_query diffère selon le type de requête employé :

      Utilisée avec une requête de type SELECT, elle renvoie un identifiant de résultat en cas de succès et FALSE en cas d'échec. Cet identifiant de résultat sera utilisé pour parcourir les données renvoyées.

      Utilisée avec tous les autres types de requête, elle renvoie TRUE en cas de succès et et FALSE en cas d'échec.
      Pour connaître le nombre de lignes concernées lors de la dernière requête INSERT, UPDATE ou DELETE, il faut utiliser la fonction mysql_affected_rows().

      Attention, il faut bien comprendre que succès ne signifie PAS qu'il s'est passé quelque chose dans la base de données.
      En effet, succès signifie que la requête à aboutie et a été traitée par MySQL.
      Ainsi, une requête SELECT qui ne renverrait aucune ligne ne renverrait pas FALSE, mais un identifiant de résultat qui pointerait sur un tableau ne comportant aucune ligne.
      De la même manière, une requête DELETE n'effaçant aucune ligne dans la base renverrait TRUE, même si aucune ligne n'a été affectée.



  4. Exploiter les résultats d'une requête de type SELECT

    1. Connaître le nombre de lignes et de colonnes du résultat

      Pour connaître le nombre de lignes retournées, on peut utiliser la fonction mysql_num_rows(). Cette fonction prend en paramètre l'identifiant de résultat retourné par mysql_query.
      De la même manière, pour connaître le nombre de champs par ligne, on peut utiliser la fonction mysql_num_fields(), qui prend également en paramètre l'identifiant de résultat retourné par mysql_query.
      Ces deux fonctions vont être utiles pour parcourir les résultats renvoyés par MySQL.


    2. La fonction mysql_fetch_array()

      Cette fonction, combinée à une instruction d'itération (comme while ou for), va permettre de récupérer les résultats de la requête ligne par ligne. Chaque ligne sera un tableau associatif, c'est à dire que les cases du tableau PHP porteront le nom de la colonne MySQL correspondante.

      $query = "SELECT * FROM matable WHERE monidentifiant > 10";
      $query_result = mysql_query($query);
      if (!$query_result) { echo ("Impossible d'afficher les résultats"); } else { echo ("Voici les résultats : <br>\n"); // On parcours chaque ligne du résultat while($row = mysql_fetch_array($query_result)) { // Pour chaque ligne retournée, on affiche ces 3 champs :
      echo $row["monidentifiant"];
      echo $row["prenom_client"]; echo $row["nom_client"];
      }
      }


    3. La fonction mysql_fetch_row()

      Cette fonction marche de la même manière que la fonction mysql_fetch_array(), sauf que les lignes de résultat sont renvoyées sous forme d'un tableau simple, c'est à dire que ses cases seront accessibles par un numéro.
      Bien que moins lisible et moins confortable, cette manière de faire peut trouver son intérêt lorsque l'on veut parcourir les différents champs retournés sans se soucier de leur nom ou de leur nombre. On peut ainsi recourir à deux itérations imbriquées, une pour parcourir les lignes de résultat, et une pour parcourir les colonnes de chaque ligne.

      $query = "SELECT * FROM matable WHERE monidentifiant > 10";
      $query_result = mysql_query($query);
      if (!$query_result) { echo ("Impossible d'afficher les résultats"); } else { // On détermine le nombre de champs du résultat $nombrechamps = mysql_num_fields($query_result); echo ("Voici les résultats : <br>\n"); // On parcours chaque ligne du résultat while($row = mysql_fetch_row($query_result)) { // Pour chaque ligne retournée, on parcours tous les champs : for ($i = 0; $i < $nombrechamps; $i++) { echo ($row[$i]); }
      }
      }

    4. Exemple

      <?php // Connexion au serveur de base de données $connect_result = mysql_connect("localhost", "raymonde", "mot_de_passe");
      if (!$connect_result) {
      echo("Impossible de se connecter au serveur de bases de données.<br>\n");
      } else {
      echo("Connecté au serveur de bases de données!<br>\n"); // Selection de la base de données $select_result = mysql_select_db("mabase");
      if (!$select_result) { echo("Impossible de se connecter à la base de données.<br>\n"); } else { echo("Connecté à la base de données!<br>\n"); // Envoi d'une requête $query = "SELECT * FROM matable WHERE monidentifiant > 10";
      $query_result = mysql_query($query);
      if (!$query_result) { echo ("Impossible d'afficher les résultats<br>\n"); } else { // On détermine le nombre de champs du résultat
      $nombrechamps = mysql_num_fields($query_result); // Et le nombre de lignes renvoyées $nombrelignes = mysql_num_rows($query_result); if ($nombrelignes == 0) { echo ("Aucun résultat trouvé!<br>\n"); } else {
      echo ("Voici les résultats : <br>\n");
      // On parcours chaque ligne du résultat
      while($row = mysql_fetch_row($query_result)) {
      // Pour chaque ligne retournée, on parcours tous les champs :
      for ($i = 0; $i < $nombrechamps; $i++) {
      // On affiche la valeur de chaque champ suivi d'un espace
      echo ($row[$i]." \n");
      } // Après chaque ligne parcourue, on saute une ligne à l'affichage echo ("<br>\n"); } } } }
      mysql_close($connect_result);
      }

      ?>



  5. Utiliser les requêtes de type INSERT, UPDATE et DELETE

    1. Les formulaires

      Les valeurs à entrer par l'utilisateur seront récupérées grâce à un formulaire HTML.

      La balise form :
      Un formulaire est délimité par les balises <form> et </form>.
      La balise d'ouverture comporte deux attributs obligatoires : method et action.

      L'attribut method représente la méthode utilisée pour transmettre les valeurs. Deux valeurs sont possibles : get et post. Avec get, les valeurs seront attachées à l'URL de la page qui va réceptionner les valeurs. Avec post, le transfert des valeurs sera invisible. Dans la pratique, post est quasiment toujours utilisé.

      L'attribut action spécifie le nom de la page HTML ou PHP qui va recevoir les valeurs. Il peut s'agir de la page contenant le formulaire ou d'une autre page.

      <form method="post" action="ma_page.php">


      La balise input :
      Différents éléments de formulaires existent : des champs de texte, des boutons radios, des cases à cocher...
      Ces éléments sont quasiment tous représentés par la balise input.
      Nous allons nous intéresser uniquement au plus simple : les champs de texte.

      La balise input comporte deux attributs obligatoires : type et name.

      L'attribut type définit le type d'objet de formulaire. Dans le cas d'un champ de texte, la valeur est text.

      L'attribut name, définit le nom qui sera associé à la valeur entrée par l'utilisateur.

      L'attribut value, facultatif, permet d'indiquer une valeur par défaut.

      <input type="text" name="champ1" value="valeur par défaut">

      donnera :


      Le bouton de soumission :
      Finalement, le dernier élément essentiel à un formulaire est le bouton de soumission, que l'utilisateur activera lorsqu'il voudra envoyer les données. Ce bouton utilise également la balise input, avec pour submit pour valeur de l'attribut type. L'attribut value permet d'indiquer le texte du bouton. L'attribut name, obligatoire, indique le nom du bouton.

      <input type="submit" name="valide_mon_form" value="Valider">

      donnera :


      Exemple de formulaire :

      <form method="post" action="ma_page.php">
        <input type="text" name="champ1" value="valeur par défaut">
        <input type="submit" name="valide_mon_form" value="Valider">
      </form>




    2. Utiliser les valeurs récupérées

      Dans la page d'arrivée du formulaire (spécifiée par la valeur de l'attribut action de la balise form), toutes les valeurs de tous les objets d'un formulaire sont présentes automatiquement sous forme de variables PHP. On peut donc accéder à la valeur de notre champ de texte champ1 au travers de la variable PHP du même nom.

      echo $champ1;

      Dès lors, on peut effectuer des traitements sur ces valeurs et les utiliser dans des requêtes.
      Pour savoir si la requête a été traitée par MySQL et a réussie, on teste la valeur de résultat de la fonction mysql_query.
      Pour connaitre le nombre de lignes affectées par la requêtes, on utilise la fonction mysql_affected_rows().

      $query = "INSERT INTO ma_table VALUES('$champ1')";
      $result = mysql_query($query);



    3. Exemple

      Cet exemple présente l'insertion d'un enregistrement dans une base de données, mais le principe est le même pour la suppression et la modification d'enregistrements.

      Dans cet exemple, la page qui présente le formulaire et la page qui en récupère les valeurs est la même. Pour savoir quoi afficher et quels traitements effectuer, on se sert du nom du bouton de soumission du formulaire, qui, s'il a été activé, sera présent en tant que variable dans la page. Ainsi, si cette variable n'existe pas, c'est qu'il faut afficher le formulaire, et si elle existe, c'est qu'il faut effectuer l'insertion dans la base de données.

      <?php if (!isset($inserer)) { ?> <form method="post" action="ma_page.php">
      <input type="text" name="nom" value="Tapez votre nom"> <input type="text" name="prenom" value="Tapez votre prénom">
      <input type="submit" name="inserer" value="Valider">
      </form> <?php
      } else { // Connexion au serveur de base de données $connect_result = mysql_connect("localhost", "raymonde", "mot_de_passe");
      if (!$connect_result) {
      echo("Impossible de se connecter au serveur de bases de données.<br>\n");
      } else {
      echo("Connecté au serveur de bases de données!<br>\n"); // Selection de la base de données $select_result = mysql_select_db("mabase");
      if (!$select_result) { echo("Impossible de se connecter à la base de données.<br>\n"); } else { echo("Connecté à la base de données!<br>\n"); // Envoi d'une requête $query = "INSERT INTO ma_table VALUES ('$nom', '$prenom')";
      $query_result = mysql_query($query);
      if (!$query_result) { echo ("L'insertion n'a pas aboutie!<br>\n"); } else { if (!mysql_affected_rows()) { echo ("L'insertion n'a pas aboutie!<br>\n"); } else { echo ("L'insertion s'est bien passée!<br>\n"); } } }
      mysql_close($connect_result);
      } }
      ?>




  6. Remarques, Trucs et astuces

    1. Masquer les messages d'erreurs

      Les appels à une base de données sont propices à génération d'erreurs. Si vous ne voulez pas que PHP affiche ses messages d'erreurs, vous pouvez bâillonner n'importe quelle fonction avec le caractère '@'.
      Cela ne marche pas uniquement avec les fonctions concernant les bases de données, mais avec toutes les fonctions de PHP.

      $retour = @fonction();



    2. Simplicité... or die()!

      Lors des différentes opérations concernant les bases de données (connexion, requête...), on a vu dans les exemples précédents que l'on testait la valeur de retour des fonctions utilisées pour savoir de quelle manière continuer le traitement (cas d'échec, cas de succès).
      Lorsque les scripts deviennent un tant soit peu compliqué, on peut rapidement arriver à un enchevêtrement de if...else imbriqués.
      Pour simplifier l'écriture des scripts, php dispose d'un élément de langage qui peut s'avérer pratique : die().
      Cet élément provoque l'interruption du script.

      Ainsi, à la place de ceci :

      $nomdelabase = "mabase"; $select_result = mysql_select_db($nomdelabase);
      if (!$select_result) { echo("Impossible de se connecter à la base de données $nomdelabase"); } else { echo("Connecté à la base $nomdelabase !"); // Traitements }

      On pourra écrire ceci :

      $nomdelabase = "mabase";
      mysql_select_db($nomdelabase)
      or die("Impossible de se connecter à la base de données $nomdelabase");

      echo ("Connecté à la base $nomdelabase !");
      //Traitements

      L'écriture en est simplifiée, mais cette manière de procéder connaît ses limites dès lors que l'on veut exécuter du code ou garder un pied de page même en cas d'erreur.
      L'élément die() est un synonyme de exit() et ils s'utilisent de la même manière.



    3. Informations sur les champs

      PHP dispose de plusieurs fonctions pour récupérer des informations sur les champs.

      La fonction mysql_list_fields() prend en paramètre un nom de base de de données et un nom de table, et renvoie un identifiant de résultat que l'on pourra utiliser avec
      - mysql_field_len()
      (taille d'un champ),
      - mysql_field_name()
      (nom d'un champ)
      - mysql_field_type()
      (type d'un champ)
      - mysql_field_flags() (attributs d'un champ)
      pour connaître les propriétés des différents champs de la table concernée.

      Cependant ces fonctions PHP m'ont parues assez imprécises. En effet les types renvoyés ne correspondaient pas toujours au type réel (par exemple un type blob pour un type text). De même, ces fonctions ne pouvaient pas dire si une clé était en texte-plein.

      Ainsi, si les informations désirées ne sont pas trop pointues (connaître le nom d'un champ, savoir s'il s'agit d'une clé primaire...) on peut très bien utiliser ces fonctions, cependant, dès lors que l'on devient exigeant, il vaut mieux coder soi-même des fonctions d'informations sur les champs à partir des requêtes mySQL "SHOW FIELDS FROM..." et SHOW KEYS FROM...".


    4. Clés étrangères

      MySQL ne gère PAS les clés étrangères! Ses concepteurs trouvaient que le système des clés étrangères présentait plus d'inconvénients que d'avantages.


    5. Autres fonctions utiles

      mysql_create_db -- Crée une base de données MySQL.
      mysql_drop_db -- Efface une base de données MySQL.
      mysql_error -- Retourne le texte associé avec l'erreur générée lors de la dernière requête.