Insertion de données dans la base

L'interface phpMyAdmin présente plusieurs inconvénients pour la saisie des données de la table SQL rounds : On préfère que l'utilisateur final insère des données dans la table rounds à l'aide d'un formulaire en ligne simple. Pour cela on doit fabriquer :
  1. Le formulaire de saisie (en HTML).
  2. Un script en PHP pour le traitement (récupération et insertion dans la table rounds) des données saisies dans les champs du formulaire.


Formulaire HTML :

Voici un exemple de formulaire HTML (fichier form.html) :

<HTML>
  <BODY>

  <FORM action="form_action.php" method="post">
    Nom&nbsp;:
    <INPUT type="text" name="nom" size="25" maxlength="30">
    <BR>
    Pr&eacute;nom&nbsp;:
    <INPUT type="text" name="prenom" size="25" maxlength="30">
    <BR>
    Sexe&nbsp;:
    <INPUT type="radio" name="sexe" value="F" checked>F
    <INPUT type="radio" name="sexe" value="M">M
    <BR>
    <INPUT type="submit" name="OK">
  </FORM>

  </BODY>
</HTML>
Visualiser ce formulaire

Ce formulaire propose des champs de différents types ("text", "radio" et "submit") contenus dans un conteneur délimité par les balises <FORM> et </FORM>.
L'attribut action de la balise <FORM> indique le programme qui devra traiter le contenu du formulaire lors de l'envoi de la requête au serveur Web. Cette requête est envoyée lors d'un clic sur un bouton de type "submit".
L'attribut method indique le mode de transmission du contenu du formulaire au serveur Web :

Les attributs size et maxlength des champs de type "text" désignent respectivement la taille visuelle du champ et le nombre max. de caractères acceptés.
L'attribut checked du champ de type "radio" indique le bouton qui doit être enfoncé par défaut.

Visualiser le formulaire ci-dessus et cliquer sur le bouton OK. Que se passe-t-il ? Pourquoi ?

Réaliser un formulaire en HTML (fichier insert_form.html, à placer dans le répertoire gaming/) pour la saisie des résultats d'un round de jeu. Les champs sont (on éclate le champ "date" en 3 champs) :

ce qui fait un total de 13 champs.

Placer le titre "Nouveau round" en haut de ce formulaire et remplacer "OK" par "Enregistrer" sur le bouton de soumission.


Traitement des valeurs saisies (insert_action.php version 1)

Une fois que l'utilisateur a rempli les champs du formulaire form.html et qu'il l'a validé en cliquant sur le bouton OK, le navigateur transmet les données au script indiqué dans l'attribut action de la balise <FORM>. Ce script PHP prend alors la main et peut accéder aux données transmises qui sont disponibles dans le tableau associatif $_POST (ou dans le tableau associatif $_GET si on a opté pour method="get" dans le formulaire HTML).

Par exemple, le script suivant va se contenter d'afficher les données transmises par le formulaire form.html ci-dessus. Il suffit pour cela de le placer dans le même répertoire que ce formulaire et de le nommer form_action.php :

<?php
  print_r($_POST);
?>

Placer ce script (en le renommant insert_action.php) dans le même répertoire que le formulaire insert_form.html.

Modifier l'attribut action de la balise <FORM> du formulaire insert_form.html, remplir ce formulaire et cliquer sur OK (penser à visualiser le code source de la page produite par le script insert_action.php).

Noter les clés du tableau associatif $_POST. Noter les valeurs des champs laissés vides.

Essayer avec des valeurs contenant des guillemets simples ', doubles " et des antislash \. Ça c'est inattendu !! C'est la faute à PHP : il est configuré pour ajouter AUTOMATIQUEMENT des antislash devant certains caractères spéciaux dans les chaînes de caractères en provenance des formulaires. C'est le mécanisme des magic quotes dont nous reparlerons plus tard ... (on pourrait le désactiver mais il se trouve qu'on n'a pas intérêt à le faire).


Traitement des valeurs saisies (insert_action.php version 2)

Dans sa version actuelle, le script form_action.php ne fait rien d'autre qu'afficher les valeurs saisies par l'utilisateur. Cette 2ème version réalise les étapes :

  1. Récupération des champs du formulaire.
  2. Fabrication d'une requête INSERT à partir des éléments du tableau associatif $_POST.
  3. Connexion au serveur MySQL.
  4. Envoi de la requête INSERT au serveur MySQL pour l'insertion d'un nouvel enregistrement dans la table "clients". N.B. : Lors d'une requête INSERT le serveur MySQL ne renvoit pas d'enregistrements, on n'a donc pas besoin de récupérer la valeur renvoyée par la fonction mysql_query() comme on l'avait fait pour la requête SELECT.
  5. Déconnexion.
  6. Affichage d'un message de réussite.
<?php
  // Récupération des champs
  $nom = $_POST['nom'];
  $prenom = $_POST['prenom'];
  $sexe = $_POST['sexe'];

  // Fabrication de la requête INSERT
  $ma_requete = "INSERT INTO `clients` (`nom`,`prenom`,`sexe`) VALUES ('$nom','$prenom','$sexe')";

  // Connexion au serveur MySQL et selection de la base "ma_base"
  $db_link = mysql_connect("localhost", "mon_username", "mon_password")
                or die(mysql_error());
  mysql_select_db("ma_base", $db_link) or die(mysql_error());

  // Envoi de la requête
  mysql_query($ma_requete,$db_link) or die(mysql_error());

  // Déconnexion
  mysql_close($db_link);

?>
<HTML>
<BODY>

<?php
  // Affichage d'un message de réussite
  echo "Le client $prenom $nom vient d'être enregistré avec succès !";
?>
</BODY>
</HTML>

Modifier le script insert_action.php pour qu'il stocke le contenu envoyé par le formulaire insert_form.html dans la table rounds.

Pour le champ "date", on le reconstruit à partir des valeurs des champs "annee", "mois" et "jour" :

<?php

  // Récupération des 13 champs du formulaire
  $jour = $_POST['jour'];
  $mois = $_POST['mois'];
  $annee = $_POST['annee'];
  $num_round = $_POST['num_round'];
  ...

  // Reconstruction du champ "date"
  $date = "$annee-$mois-$jour";

  ...

?>
<HTML>
<BODY>

...

</BODY>
</HTML>

Faire afficher un message de réussite du genre :

Le round

   date : 2003-02-05
   round : 1
   jeu : SoF2
   ...

vient d'être enregistré avec succès !

Insérer quelques enregistrements à l'aide du formulaire. Visualiser le résultat sur la base avec phpMyAdmin.

Essayer d'insérer 2 enregistrements avec la même date et le même numéro de round.

Insérer des enregistrements contenant des ', des " et des \. Observer le message de réussite. Le comparer aux valeurs REELLEMENT enregistrées dans la base (avec phpMyAdmin).

Visualiser le contenu de la table rounds avec le script select_all.php.


Traitement des valeurs saisies (insert_action.php version 3)

On voudrait rendre obligatoires les champs "jour", "mois", "annee", "num_round", "place1" à "place6".
Il faudrait commencer par modifier le formulaire pour signaler ces champs obligatoires mais c'est insuffisant car, malgré cette précaution, l'utilisateur final pourra encore oublier un champ obligatoire sans se faire engueuler !
Pour l'en empêcher on va implémenter dans le script insert_action.php un contrôle des valeurs saisies avant leur insertion dans la base.

Par exemple pour le contrôle du champ obligatoire "place1" :

<?php

  ...

  $place1 = $_POST['place1'];

  if ($place1 == "") {
	echo "ERREUR DE SAISIE : Le champ &quot;place1&quot; est obligatoire !";
	exit;
  }

  ...

?>
...

Implémenter dans insert_action.php le contrôle des champs obligatoires.

Le contrôle des champs obligatoires, tel qu'on vient de l'implémenter, présente un défaut au niveau de la forme : le code qu'on a écrit est répétitif. On effectue 10 fois de suite le même test (sur des variables différentes) et on affiche 10 fois de suite le même message (au nom de champ près) en cas d'erreur de saisie.
Les inconvénients qui en découlent sont :

Une meilleure façon d'implémenter le contrôle des champs numériques est de CRÉER UNE FONCTION.

La fonction suivante compare le contenu de son argument à la chaîne de caractère "", puis, en cas d'égalité, affiche un message d'erreur et interrompt l'exécution du script.

<?php

  // FONCTION exit_if_empty() VERSION 1
  function exit_if_empty($champ)
  {
	if ($champ == "") {
		echo "ERREUR DE SAISIE : Ce champ est obligatoire !";
		exit;
	}
	return;
  }

  // Controle des champs
  $jour = $_POST['jour'];
  exit_if_empty($jour);

  $mois = $_POST['mois'];
  exit_if_empty($mois);

  ...

?>
...

Modifier le script insert_action.php pour que les 10 champs obligatoires soient contrôlés par des appels à la fonction exit_if_empty().

Essayer d'insérer quelques enregistrements à l'aide du formulaire insert_form.html en oubliant de remplir certains champs obligatoires. Le message d'erreur affiché par la fonction exit_if_empty() est-il adapté ?

Pour que le message d'erreur affiché par la fonction exit_if_empty() soit utile, il doit dire à l'utilisateur à quel endroit du formulaire s'est produite l'erreur. Pour cela on a besoin d'ajouter un deuxième argument à la fonction :

<?php

  // FONCTION exit_if_empty() VERSION 2
  function exit_if_empty($champ,$nom_du_champ)
  {
	if ($champ == "") {
		echo "ERREUR DE SAISIE : ";
		echo "Le champ &quot;$nom_du_champ&quot; est obligatoire !";
		exit;
	}
	return;
  }

  ...

?>
...

Adapter le script insert_action.php et tester.


Traitement des valeurs saisies (insert_action.php version 4)

Le contrôle exercé par la fonction exit_if_empty() n'est pas suffisant pour les champs "jour", "mois", "annee" et "num_round" qui, en plus d'être obligatoires, doivent être des nombres.
Le champ "nb_joueurs" doit aussi être un nombre mais il n'est pas obligatoire.

Pour le contrôle de ces 5 champs, on va créer la fonction :

<?php

  // FONCTION exit_if_not_integer() VERSION 1
  function exit_if_not_integer($champ,$nom_du_champ)
  {
	if (!is_numeric($champ)) {
		echo "ERREUR DE SAISIE : ";
		echo "Le champ &quot;$nom_du_champ&quot; doit &ecirc;tre un nombre !";
		exit;
	}
	return;
  }

  ...

?>
...

Le contrôle du champ "jour" se fait en appelant successivement les fonctions exit_if_empty() et exit_if_not_integer() :

<?php

  // Controle du champ "jour"
  $jour = $_POST['jour'];
  exit_if_empty($jour,"jour");
  exit_if_not_integer($jour,"jour");

  ...

?>
...

Adapter le script insert_action.php et tester.

Essayer de saisir "-4" ou ".4" dans le champ "jour" du formulaire insert_form.html.

Dans cette 2ème version, la fonction exit_if_not_integer() rejettera toute chaîne de caractères qui ne contient pas que des chiffres (c'est-à-dire, qui contient au moins un caractère qui n'est pas un chiffre).

<?php

  // FONCTION exit_if_not_integer() VERSION 2
  function exit_if_not_integer($champ,$nom_du_champ)
  {
	if (ereg("[^0-9]",$champ)) {
		echo "ERREUR DE SAISIE : ";
		echo "Le champ &quot;$nom_du_champ&quot; doit &ecirc;tre un nombre !";
		exit;
	}
	return;
  }

  ...

?>
...

Adapter le script insert_action.php et tester.

N.B. : Si le contrôle des champs n'avait pas été confié à des fonctions, cette dernière modification aurait été plus laborieuse car on aurait dû faire LA MÊME CORRECTION à 5 endroits différents du script.

Avec cette dernière modification le contrôle des champs n'est toujours pas parfait : l'utilisateur final peut encore faire des bêtises comme, par exemple, saisir 0 ou un nombre > 31 dans le champ "jour".


Page d'accueil de Hervé PagèsValid HTML 4.01!Contact : herve.pages@free.fr