Traitement d'un formulaire dans un while

Résolu/Fermé
janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 - Modifié par irongege le 8/07/2013 à 16:57
janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 - 17 juil. 2013 à 18:04
BONSOIR,

Je cherche sans succès comment traiter un formulaire dans un while.

Je m'explique :

J'ai une base de données répertoriant des individus.

Je les fais apparaître dans une boucle, et je voudrai qu'à chaque individu je dispose d' un formulaire me permettant d'effectuer des modifs ou compléments d'information.

Pour cela, il faut que la boucle s'arrête le temps de compléter les infos de l'individu, et leur validation enclanche la présentation de la fiche suivante.

Le processus continue jusqu'à la dernière fiche.

Si je procède comme ceci, j'ai tous mes individus à la suite les uns des autres !...
<?php
session_start();
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<title>reponse administration</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
</head>
 
<body>
 
<?php
<p>
$bdd = new PDO('mysql:host=lxxxxx.fr.mysql;dbname=nnnnn', 'ccccc', 'yyyyy', $pdo_options);
 
$reponse = $bdd->query('SELECT * FROM identite');
WHILE($donnees = $reponse->fetch())
{
?>
<form method="post" action="modif.php">
 
<label for="prenom">Prénom :               </label>
<INPUT type="prenom" name="prenom" value = "<?php echo $donnees['Prenom'];?>" id="prenom" autofocus required/>
<br />
 
<label for="nom">Nom :                   </label>
<INPUT type="text" name="nom" value = "<?php echo $donnees['Nom'];?>" id="nom" required/>
<br />
 
<label for="adresse">Adresse :              </label>
<INPUT type="text" name="adresse" value = "<?php echo $donnees['Adresse'];?>" id="adresse" required/>
<br />
 
<label for="cp">CP:                       </label>
<INPUT type="text" name="cp" value = "<?php echo $donnees['CP'];?>" id="cp" required/>
<br />
 
<label for="ville">Ville :                    </label>
<INPUT type="text" name="ville" value="<?php echo $donnees['Ville'];?>" id="ville" required/>
<br />
 
<label for="tel">Téléphone :           </label>
<INPUT type="text" name="tel" value = "<?php echo $donnees['Tel'];?>" id="tel" />
<br />
 
<label for="portable">Portable :              </label>
<INPUT type="text" name="portable" value = "<?php echo $donnees['Portable'];?>" id="portable" />
<br />
 
<label for="mail">Mail  :                     </label>
<INPUT type="email" name="email" value = "<?php echo $donnees['Mail'];?>"/>
<br />
 
</p>
                      <INPUT type="submit" value="Modifier" /> <INPUT type="reset" value="Effacer" />
</form>
<?php
}
 
 
?>
</body>
</html>



Comment interrompre le while et le faire redémarrer après avoir cliqué sur submit ?

Merci de votre aide.

3 réponses

janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 3
5 juil. 2013 à 09:10
Voici le cheminement du programme pour la communauté :
2 fichiers. Un fichier saisie et un fichier modif.
Fichier saisie:
1°) initialisation à 1 de l'ID des membres (démarre à la première fiche)
if (isset($_GET['id']))
{      $id = $_GET['id'];
}else{
	$reponse = $bdd->query("SELECT * FROM identite");
	$count = 0;
	WHILE($donnees = $reponse->fetch())
	{
		$count = $count + 1;
	}
	$id = 1;
	//echo 'id n\'existe pas';
}

2°) Appel de la première fiche
$reponse = $bdd->query("SELECT * FROM identite WHERE id = '$id'");
$donnees = $reponse->fetch(); ?> 

3°) création du formulaire
<form>
........
........
<input type = "hidden" name = "nombre" value = "<?php echo $id;?>" />
// envoi dans une variable  hidden de l'id en cours
</form>


Fichier modif
Après avoir récupéré les champs envoyés avec POST,
// on récupère la variable 'nombre'
if (isset($_POST['nombre'])) 
{ $nombre = $_POST['nombre'];
}

// On se connecte a MySQL
$pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
$bdd = new PDO('mysql:host=xxxxx.fr.mysql;dbname=lyyyyy', 'nnnn', 'ooooo', $pdo_options);
$req = $bdd->prepare("UPDATE identite SET Adresse = :nvadresse, CP = :nvCP, Ville = :nvville, Tel = :nvtel, Portable = :nvportable, Mail = :nvemail WHERE Nom = '$nom' AND Prenom = '$prenom' ");
			$req->execute(array(
			'nvadresse' => $adresse,
			'nvCP' => $cp,
			'nvville' => $ville,
			'nvtel' => $tel,
			'nvportable' => $portable,
			'nvemail' => $mail
			));

puis on donne la possibilité d'avancer ou de reculer dans la liste en envoyant la variable GET :
<a href="saisie.php?id=<?php echo $nombre-1;?>">précédent</a><a href="saisie.php?id=<?php echo $nombre;?>">identique</a><a href="saisie.php?id=<?php echo $nombre+1;?>">suivant</a>


Voilà, j'espère que certains pourront en profiter.
1
JooS Messages postés 2465 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
Modifié par JooS le 5/07/2013 à 18:40
1 - C'est possible de faire un "count" directement dans le SQL.

2 - Le premier ID ne peut pas toujours être égale a 1, imaginez que vous deviez supprimer le premier tuple de votre table, alors le premier ID deviendra 2, donc il est préférable de le récupérer via une requête.

3 - Puisque vous utilisez PDO, quand il y a des variables a inclure dans votre requête, il est conseillé d'utiliser des requêtes préparés (comme vous l'avez presque fait avec UPDATE).
Si vous remarquez bien, dans le premier test, vous ne vérifiez pas si "$_GET['id']" est bien un nombre, donc une personne mal intentionné peut facilement mettre n'importe quoi dans cette variable, or, une injection SQL peut très facilement être réalisée.
Alors il faut toujours vérifier le contenu des variables dont l'utilisateur a accès (Variables globales) + utiliser les requêtes préparés correctement.
PS : C'est pour ça que dans l'exemple que j'avais donné, j'ai préféré le faire avec SESSION au lieu des autres, car l'utilisateur n'a pas un accès direct a cette variable, donc il ne pourra pas modifier son contenu.

4 - Il est conseillé de mettre votre script de connexion a la base de données dans un fichier appart, et d'inclure ce fichier la ou vous souhaitez, vous gagnerais en lignes de code, en temps, et votre travail sera plus organisé, imaginez que vous ayez a modifier le nom de votre base de données, vous devriez parcourir tout vos fichiers, alors que si vous utiliser la méthode de l'inclusion, alors vous n'aurez a modifier qu'un seul fichier.

5 - L'identifiant ici c'est "id", donc si vous mettez "WHERE Nom = ? AND Prenom = ?", vous pourrez tomber sur 2 ou plusieurs résultats, car logiquement c'est possible que deux personnes portent le même nom et prénom, donc il faut faire "WHERE id = ?", c'est pour ce genre de soucis qu'une clé primaire nous sert après tout.

6 - A la fin, Suivant et précédant, vous ne pouvez pas mettre +1 pour le suivant et -1 pour le précédant, car c'est toujours possible de supprimer un individu au début, milieu ou a la fin de la table, donc a tout moment, vous pourrez tomber sur un identifiant qui n'existe pas réellement dans la base de données, ce qui engendrera surement des erreurs.

<?php
try {
 $pdo_options[PDO::ATTR_ERRMODE] = PDO::ERRMODE_EXCEPTION;
 $bdd = new PDO('mysql:host=localhost;dbname=test', 'root', '', $pdo_options);
}
catch(Exception $e) {
 die('Error : ' . $e->getMessage());
}

session_start();

// Traitement du formulaire si envoyé
if(isset($_POST) AND !empty($_POST) AND isset($_SESSION['idIndividuEnCours'])) {
 try {
  $move = '';
  $save = false;
  
  if($_POST['action'] == 'Enregistrer') {
   $save = true;
  }
  elseif($_POST['action'] == 'Enregistrer et precedant') {
   $move = 'Prev';
   $save = true;
  }
  elseif($_POST['action'] == 'Enregistrer et suivant') {
   $move = 'Next';
   $save = true;
  }
  elseif($_POST['action'] == 'Suivant') {
   $move = 'Next';
  }
  elseif($_POST['action'] == 'Precedant') {
   $move = 'Prev';
  }
  
  if($save) {
   // Vérifier les valeurs des variables
   // ICI ...
   
   // Mise a jour des informations
   $req = $bdd->prepare('
       UPDATE identite 
       SET Nom = :val1, Prenom = :val2, Adresse = :val3, CP = :val4, Ville = :val5, Tel = :val6, Portable = :val7, Mail = :val8 
       WHERE id = :id');
   $req->bindParam(':val1', $_POST['Nom'], PDO::PARAM_STR, 45);
   $req->bindParam(':val2', $_POST['Prenom'], PDO::PARAM_STR, 45);
   $req->bindParam(':val3', $_POST['Adresse'], PDO::PARAM_STR, 45);
   $req->bindParam(':val4', $_POST['CP'], PDO::PARAM_STR, 45);
   $req->bindParam(':val5', $_POST['Ville'], PDO::PARAM_STR, 45);
   $req->bindParam(':val6', $_POST['Tel'], PDO::PARAM_STR, 45);
   $req->bindParam(':val7', $_POST['Portable'], PDO::PARAM_STR, 45);
   $req->bindParam(':val8', $_POST['Mail'], PDO::PARAM_STR, 45);
   $req->bindParam(':id', $_SESSION['idIndividuEnCours'], PDO::PARAM_INT);
   $req->execute();
  }
  
  if($move == 'Next') {
   // Recuperer l'id de la personne suivante
   $req = $bdd->prepare('SELECT id FROM identite WHERE id > :id LIMIT 0, 1');
   $req->bindParam(':id', $_SESSION['idIndividuEnCours'], PDO::PARAM_INT);
   $req->execute();
   $data = $req->fetch(PDO::FETCH_ASSOC);

   if(!empty($data)) $_SESSION['idIndividuEnCours'] = $data['id'];
  }
  elseif($move == 'Prev') {
   // Recuperer l'id de la personne precedante
   $req = $bdd->prepare('SELECT id FROM identite WHERE id < :id ORDER BY id DESC LIMIT 0, 1');
   $req->bindParam(':id', $_SESSION['idIndividuEnCours'], PDO::PARAM_INT);
   $req->execute();
   $data = $req->fetch(PDO::FETCH_ASSOC);

   if(!empty($data)) $_SESSION['idIndividuEnCours'] = $data['id'];
  }
 }
 catch(Exception $e) {
  die('Erreur : Formulaire incorrect.');
 }
}

// Récuperer l'id en cours
$idIndividu = (isset($_SESSION['idIndividuEnCours']) AND is_numeric($_SESSION['idIndividuEnCours'])) ? $_SESSION['idIndividuEnCours'] : null;

// Si premiere visiste sur le site
if($idIndividu == null) {
 $req = $bdd->query('SELECT MIN(id) AS min, COUNT(*) AS total FROM identite');
 $data = $req->fetch();
 
 $idIndividu = $data['min'];
 
 // Si la table est vide
 if($idIndividu == null) die('Base de données vide.');
 else $_SESSION['idIndividuEnCours'] = $idIndividu;
}

// Chargement des informations
$req = $bdd->prepare('SELECT * FROM identite WHERE id = :id');
$req->bindParam(':id', $idIndividu, PDO::PARAM_INT);
$req->execute();
$data = $req->fetch(PDO::FETCH_ASSOC);

// Affichage du formulaire
echo '<form method="post">';

foreach($data AS $key=>$value)
 if($key != 'id') 
  echo '<p><input type="text" name="' . $key. '" value="' . $value . '"></p>';
  
echo '<input type="submit" name="action" value="Enregistrer et precedant">';
echo '<input type="submit" name="action" value="Enregistrer">';
echo '<input type="submit" name="action" value="Enregistrer et suivant"><br>';
echo '<input type="submit" name="action" value="Precedant">'; 
echo '<input type="submit" name="action" value="Suivant"></form>';
?>
0
janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 3
6 juil. 2013 à 12:16
merci de toutes ces précisions qui fiabilisent l'ensemble du programme.
Elles me seront très utiles.
D'autre part, je suis confus d'avoir donné des pistes de solutions aussi approximatives.
Bonne continuation à tous.
0
janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 3
8 juil. 2013 à 16:54
Juste encore une question s'il vous plaît :
Dans mes champs affichés, j'en ai plusieurs qui sont numériques. Il est donc important d'affecter un label à chaque champ. Dans la méthode utilisée, je ne comprends pas bien la syntaxe:
foreach($data AS $key=>$value)
if($key != 'id')
echo '<p><input type="text" name="' . $key. '" value="' . $value . '"></p>';
Où mettre les labels nom, prénom, adresse etc...
Merci d'avance.
0
JooS Messages postés 2465 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
9 juil. 2013 à 01:17
... important d'affecter un label à chaque champ ...
Que voulez vous dire par label ?
0
janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 3
9 juil. 2013 à 09:01
J'ai besoin de mettre le titre des champs pour que l'utilisateur sache quel champ il modifie :
par exemple :
nom : "champ nom"
prenom : "champ prenom"
Tél : "champ téléphone"
portable : "champ portable"
annee de naissance : champ année

S'il n'y a pas de dénomination avant le champ, l'utilisateur ne peut pas deviner quelle est la nature du champ, surtout s'il s'agit d'un nombre impersonnel.
Dans un écriture traditionnelle on écrirait :
<label for="portable">Portable </label><INPUT type="text" name="portable" < />
0
JooS Messages postés 2465 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
4 juil. 2013 à 20:47
Salut,

Ce que tu demande est impossible en PHP.

PHP est un langage qui s'exécute coté serveur, or, aucune interaction ne peut être réaliser lors du chargement de la page.

Donc il te faut quelque chose coté client, autrement dis, du Javascript !

Par contre, c'est possible de faire un truc semblable avec PHP, mais pas a l'aide d'une boucle.
Tu dois jouer avec les variable globales, GET, POST, SESSION ou même COOKIE.

On prend un exemple avec SESSION.

Si la variable de session n'existe pas, alors tu en initialise une avec le premier individu de ta liste, en récupérant son ID (ou toutes ses infos) via une requête.
$_SESSION['individuEnCours'] = $id;

Tu affiche le formulaire en fonction de cette variable de session.

Une fois le formulaire envoyé, les informations sont enregistrés dans la BD via une requête SQL, tu récupère l'ID de l'individu suivant, tu affecte son ID a la variable de session, et tu actualise la page.

Et rebelote, en gros c'est quelque chose du genre.

Sinon, avec jQuery c'est bien meilleur.
0
janmar Messages postés 148 Date d'inscription vendredi 17 mai 2013 Statut Membre Dernière intervention 29 août 2015 3
4 juil. 2013 à 22:44
Merci JooS,
Je me suis débrouillé en PHP, avec une variable GET qui fait la navette entre la requête sql, le formulaire et le traitement de ce dernier. Ça marche plutôt bien, mais quelle galère à programmer.
Je n'envisage pas pour le moment une solution JQuery, je ne maîtrise pas du tout la chose.
0
JooS Messages postés 2465 Date d'inscription mardi 22 janvier 2008 Statut Membre Dernière intervention 8 juin 2016 228
5 juil. 2013 à 02:20
Je t'en pris, et bonne chance.
0