Page 1 sur 1

Insertion Mysql de donnees $_POST

Posté : 04 mai 2009, 16:37
par Jackisback
Bonjour,

J'ai cette requete pour effectuer l'insertion en BDD:

$reqteste = "INSERT INTO reponses (
		idtest,
		idutil,
		idaff,
		valeur)
	VALUES(
		'".$_SESSION['idtester']."',
		'".$_SESSION['idutilisateur']."',
		'".$_SESSION['idaffirm']."',
		'".$_POST['$affirmation['valeur']']."'
		)";

Et voici le champ de mon questionnaire envoyé avec la méthode POST:
echo '<li><input type="radio" name="'.$affirmation['idtheme'].'" value="'.$affirmation['idaff'].'" />'.$affirmation['valeur']."</li>";

et il me retourne ce message d'erreur:

Parse error: parse error, expecting `']'' à la ligne 42
Voici la ligne 42:

'".$_POST['$affirmation['valeur']']."'

Voici le code du formulaire de la page précédente:
echo '<div id="formtest">
<form id="form1" name="form1" method="post" action="nouveautestsuite.php">
	<ul class="theme">
';

while ($themes=mysql_fetch_assoc($res)){
		
	echo "<li>".$themes['intitule']."</li>\n";
	$resaff=mysql_query("SELECT * FROM affirmations WHERE idtheme=".$themes['idtheme']);

	echo '<ul class="affirmation">';
	while ($affirmation=mysql_fetch_assoc($resaff)){

		echo '<li><input type="radio" name="'.$affirmation['idtheme'].'" value="'.$affirmation['idaff'].'" />'.$affirmation['valeur'].'</li>';
	
	}
	echo '</ul>';
}
echo '
</ul>
<input type="submit" value="Le vérificateur clique ici" />

</form>
</div>
Je n'arrive pas à trouver la syntaxe correcte, donc si quelqu'un pouvait m'aider svp ...

Bonne journée.

Posté : 04 mai 2009, 18:03
par Ryle
tu n'aurais pas une paire d'apostrophes en trop pour récupérer le nom du champ :
$_POST[$affirmation['valeur']]
//au lieu de 
$_POST['$affirmation['valeur']']

Posté : 04 mai 2009, 18:29
par zeus
Est-ce que tu es conscient que l'insertion de données provenant de l'utilisateur ($_POST) sans aucune vérification est une faille de sécurité ?

Si j'arrive à t'envoyer "l'erreur" dans le champ POST, ta requête explose. (et ne crois pas, c'est très simple à faire)
Si je saisie "1'; DELETE * FROM administrateur; --" je peux essayer de détruire des tables ;)

la bonne manière de faire est de passer toutes les valeurs qui proviennent du client (POST, GET, COOKIE) à la fonction mysql_real_escape_string() avant de les passer dans une requête.

Posté : 04 mai 2009, 18:59
par Jackisback
Pour RYLE ...

J'ai fais ce que tu m'as dis mais ça ne change rien ...

J'ai fais un :
print_r ($_POST);
Mais il ne m'affiche que :

Code : Tout sélectionner

Array ( [1] => 1 )
Et en aucun cas l'affirmation choisis parmis les 5 proposées dans mon questionnaire.

-----------

Et pour ZEUS .....

Je n'en suis pas encore à la sécurisation ...

Pour moi ça alourdirais mes scripts ... déjà qu'ils ne fonctionnent pas tous alors je vais d'abord essayer de corriger tout ça après je sécuriserai ...

@ +

Posté : 04 mai 2009, 19:52
par sadeq
J'avoue que j'ai un p'tit malaise logique pour comprendre la logique de ton code, alors j'ai quelques remarques:
à part l'erreur de syntaxe déjà corrigée par RYLE ;
Il y a une différence entre le nom du champ radio que tu imprime (idtheme) et celui que tu essaye de lire à partir du POST (valeur)

Voici donc le correctif littéral selon le nom des radios que tu imprime:
echo '<li><input type="radio" name="'.$affirmation['idtheme'].'" value="'.$affirmation['idaff'].'" />'.$affirmation['valeur']."</li>";
$reqteste = "INSERT INTO reponses (
        idtest,
        idutil,
        idaff,
        valeur)
    VALUES(
        '".$_SESSION['idtester']."',
        '".$_SESSION['idutilisateur']."',
        '".$_SESSION['idaffirm']."',
        '".$_POST[$affirmation['idtheme']]."'
        )"; 
Mais pourque ça marche, il faut que la variable $affirmation['idtheme'] existe dans ce contexte.

MAIS, si l'on met $affirmation['idtheme'] à cet emplacement de la requête, cela ne correspond pas à la valeur attendue par INSERT puisque $affirmation['idtheme'] contient en fait $affirmation['idaff'] selon tes radios boutons.

Sauf explications de ta part, à mon avis le modèle suivant est plus cohérent:
echo '<li><input type="radio" name="'.$affirmation['idtheme'].$affirmation['idaff'].'" value="'.$affirmation['valeur'].'" />'.$affirmation['valeur']."</li>";
ici, la réponse à une question du test est présentée sous un nom composé du thème et l'affirmation idtheme et idaff. Ce qui rend unique un nom de réponses. Mais l'important est que chaque case radio porte la valeur $affirmation['valeur'] qu'on souhaite utiliser ultérieurement dans l'INSERT.

Conformément à ce codage de nom de case, au niveau de la requête voici comment lire le POST des cases:
$reqteste = "INSERT INTO reponses (
        idtest,
        idutil,
        idaff,
        valeur)
    VALUES(
        '".$_SESSION['idtester']."',
        '".$_SESSION['idutilisateur']."',
        '".$_SESSION['idaffirm']."',
        '".$_POST[$affirmation['idtheme'].$affirmation['idaff']]."'
        )"; 
Bien sûr, les 2 variables $affirmation['idtheme'] et $affirmation['idaff'] doivent être connues dans ce contexte. Je suppose que tu mets cet INSERT dans une boucle qui lit $affirmation à partir de la base.

Posté : 04 mai 2009, 22:19
par Jackisback
bon j'ai modifié comme tu m'as dis ...

Voilà ce que j'obtiens:
Array
(
    [11] => Je suis toujours d'accord
    [31154] => J'accepte toujours avec joie
    [32157] => Je suis fort
)
pour les numéros idaff (id affirmations qui correspond à l'id AutoIncrementé de ma table affirmations) et idtheme (id themes qui correspond à l'id AI de ma table themes) c'est ok.

Ensuite pour les affirmations c'est aussi ok ...

Par contre je ne pense pas qu'il faille écrire:
'".$_POST[$affirmation['idtheme'].$affirmation['idaff']]."'
Car moi ce que je veux enregistrer, c'est l'affirmations qui à été choisis par l'utilisateur et donc je devrais plutot spécifier ceci dans ma requete INSERT:
'".$_POST[$affirmation['valeur']."'
Par contre dans mes boutons radios, je peux sélectionner les 5 affirmations au lieu d'une seule ...

Normale, tu vas me dire car les deux id sont concatener et qu'un id et unique à chaque fois normal que je ne puisse pas en sélectionner qu'un seul ...

Je vais gratter un peu ...

En tout cas merci ça m'a déjà bien aidé ...

Bye

Posté : 05 mai 2009, 11:04
par Jackisback
Voici la première page du test:

<?php

$liste_themes_coches="";
foreach ($_POST as $t=>$v){ //$t themes, $v value
	$liste_themes_coches.="'$t',";
}
$liste_themes_coches=substr($liste_themes_coches,0,-1);

$requete="SELECT * FROM themes WHERE idtheme in ($liste_themes_coches)";
$res=mysql_query($requete);
echo mysql_error();

echo '<div id="formtest">
<form id="form1" name="form1" method="POST" action="nouveautestsuite.php">
	<ul class="theme">
';

while ($themes=mysql_fetch_assoc($res)){
		
	echo "<li>".$themes['intitule']."</li>\n";
	$resaff=mysql_query("SELECT * FROM affirmations WHERE idtheme=".$themes['idtheme']);
	
	echo '<ul class="affirmation">';
	while ($affirmation=mysql_fetch_assoc($resaff)){
		//echo '<li><input type="radio" name="'.$affirmation['idtheme'].'" value="'.$affirmation['idaff'].'" />'.$affirmation['valeur'].'</li>';
		//echo '<li><input type="radio" name="'.$affirmation['idtheme'].$affirmation['idaff'].'" value="'.$affirmation['valeur'].'" />'.$affirmation['valeur']."</li>";
		echo '<li><input type="radio" name="'.$affirmation['idtheme'].'" value="'.$affirmation['valeur'].'" />'.$affirmation['valeur']."</li>";
	
	}
	echo '</ul>';
}
echo '
</ul>
<input type="submit" value="Le vérificateur clique ici" />

</form>
</div>';
?>

Voici la deuxième page du test:

<?php

$affirmation2 = $_POST[$affirmation['valeur']];

//On insère les resultats du test de la personne testee
$reqteste = "INSERT INTO reponses (
		idtest,
		idutil,
		idaff,
		valeur)
	VALUES(
		'',
		'".$_SESSION['idutilisateur']."',
		'".$_SESSION['idaffirm']."',
		'".$affirmation2."'
		)";

mysql_query($reqteste);

$requete="SELECT * FROM themes";
$res=mysql_query($requete);

echo '<div id="formtest">
<form id="form1" name="form1" method="POST" action="nouveautestfin.php">
	<ul class="theme">
';

while ($themes=mysql_fetch_assoc($res)){
		
	echo "<li>".$themes['intitule']."</li>\n";
	$resaff=mysql_query("SELECT * FROM affirmations WHERE idtheme=".$themes['idtheme']);

	echo '<ul class="affirmation">';
	while ($affirmation=mysql_fetch_assoc($resaff)){
		echo '<li><input type="radio" name="'.$affirmation['idtheme'].'" value="'.$affirmation['valeur'].'" />'.$affirmation['valeur']."</li>";
	
	}
	echo '</ul>';
}
echo '
</ul>
<input type="submit" value="Afficher les résultats" />
</form>
</div>';
?>
[Note : ce message a été posté de manière anonyme avant d'être réattribué à son auteur]

Posté : 06 mai 2009, 00:43
par sadeq
Correction:
$affirmation2 = $_POST[$affirmation['idtheme']]; 

Posté : 06 mai 2009, 11:42
par sadeq
Pour plus de compréhension, voici un exemple que j'ai adapté à ton cas:

La base de données est nommée QCM:

Code : Tout sélectionner

-- phpMyAdmin SQL Dump -- version 3.1.3 -- http://www.phpmyadmin.net -- -- Serveur: localhost -- Généré le : Mer 06 Mai 2009 à 11:27 -- Version du serveur: 5.1.32 -- Version de PHP: 5.2.9-1 SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO"; -- -- Base de données: `qcm` -- -- -------------------------------------------------------- -- -- Structure de la table `affirmations` -- -- Création: Mer 06 Mai 2009 à 11:25 -- Dernière modification: Mer 06 Mai 2009 à 11:25 -- CREATE TABLE IF NOT EXISTS `affirmations` ( `id` int(11) NOT NULL AUTO_INCREMENT, `valeur` varchar(255) DEFAULT NULL, `points` int(11) DEFAULT NULL, `idtheme` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `aff_unique` (`idtheme`,`valeur`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=50 ; -- -- Contenu de la table `affirmations` -- INSERT INTO `affirmations` (`id`, `valeur`, `points`, `idtheme`) VALUES (1, 'Souper aux chandelles', 4, 1), (2, 'Parc d''amusement', 2, 1), (3, 'Patins à roues alignées au parc', 5, 1), (4, 'Concert Rock', 1, 1), (5, 'Cinéma', 3, 1), (6, 'Rock and roll', 2, 2), (7, 'Alternatif', 1, 2), (8, 'Soft Rock', 4, 2), (9, 'Classique', 5, 2), (10, 'Chrétien', 3, 2), (11, 'Comédie', 2, 3), (12, 'Horreur', 1, 3), (13, 'Comédie musicale', 3, 3), (14, 'Romantique', 4, 3), (15, 'Documentaire', 5, 3), (16, 'Serveur', 4, 4), (17, 'Sportif', 5, 4), (18, 'Professeur', 3, 4), (19, 'Policier', 2, 4), (20, 'Barman', 1, 4), (21, 'Entraînement', 5, 5), (22, 'Lecture', 4, 5), (23, 'Télévision', 2, 5), (24, 'Radio', 1, 5), (25, 'Dormir', 3, 5), (26, 'Jaune', 1, 6), (27, 'Blanc', 5, 6), (28, 'Bleu poudre', 3, 6), (29, 'Sarcelle', 2, 6), (30, 'Rouge', 4, 6), (31, 'Crème glacée', 3, 7), (32, 'Pizza', 2, 7), (33, 'Sushi', 1, 7), (34, 'Pâtes', 4, 7), (35, 'Salade', 5, 7), (36, 'Halloween', 1, 8), (37, 'Noël', 3, 8), (38, 'Nouvel an', 2, 8), (39, 'St-valentin', 4, 8), (40, 'Action de grâce', 5, 8), (41, 'Paris', 4, 9), (42, 'Espagne', 5, 9), (43, 'Las Vegas', 1, 9), (44, 'Hawaï', 4, 9), (45, 'Hollywood', 3, 9), (46, 'Quelqu''un d''intelligent', 5, 10), (47, 'Quelqu''un qui est très beau', 2, 10), (48, 'Quelqu''un qui s''amuse toujours', 1, 10), (49, 'Quelqu''un de très émotif', 3, 10); -- -------------------------------------------------------- -- -- Structure de la table `reponses` -- -- Création: Mer 06 Mai 2009 à 11:27 -- Dernière modification: Mer 06 Mai 2009 à 11:27 -- Dernière vérification: Mer 06 Mai 2009 à 11:27 -- CREATE TABLE IF NOT EXISTS `reponses` ( `id` int(11) NOT NULL AUTO_INCREMENT, `idutil` varchar(255) DEFAULT NULL, `idaff` int(11) DEFAULT NULL, PRIMARY KEY (`id`), UNIQUE KEY `reponse_unique` (`idutil`,`idaff`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ; -- -- Contenu de la table `reponses` -- -- -------------------------------------------------------- -- -- Structure de la table `test` -- -- Création: Mer 06 Mai 2009 à 11:25 -- Dernière modification: Mer 06 Mai 2009 à 11:25 -- CREATE TABLE IF NOT EXISTS `test` ( `id` int(11) NOT NULL AUTO_INCREMENT, `intitule` varchar(255) DEFAULT NULL, `regles` varchar(255) DEFAULT NULL, `interpretation` text, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=2 ; -- -- Contenu de la table `test` -- INSERT INTO `test` (`id`, `intitule`, `regles`, `interpretation`) VALUES (1, 'Vous êtes vous déjà demandé quel bonhomme de dessin animé vous étiez ? Une équipe de chercheurs ont analysé les personnalités des Looney Tunes, Répondez à chaque question la réponse la plus près de la réalité présentement, additionnez ensuite les points', '', ''); -- -------------------------------------------------------- -- -- Structure de la table `themes` -- -- Création: Mer 06 Mai 2009 à 11:25 -- Dernière modification: Mer 06 Mai 2009 à 11:25 -- CREATE TABLE IF NOT EXISTS `themes` ( `id` int(11) NOT NULL AUTO_INCREMENT, `intitule` varchar(255) DEFAULT NULL, `idtest` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=11 ; -- -- Contenu de la table `themes` -- INSERT INTO `themes` (`id`, `intitule`, `idtest`) VALUES (1, 'Quelle serait votre soirée rencontre parfaite ?', 1), (2, 'Quel est votre style musical favori ?', 1), (3, 'Quel est votre genre de film préféré ?', 1), (4, 'Quel emploi choisiriez vous ? (Si les choix suivants étaient les seuls que vous auriez)', 1), (5, 'Que feriez vous si vous aviez une heure à perdre ?', 1), (6, 'Quelle est votre couleur préférée ?', 1), (7, 'Que mangeriez vous maintenant ?', 1), (8, 'Quelle est votre fête préférée ?', 1), (9, 'Quelle serait votre destination idéale ?', 1), (10, 'Avec qui préféreriez vous passer du temps?', 1);
Le programme est composé de 3 pages :
  • 1. Introduction au test (introduireAuTest.php) qui identifie l'utilisateur et lui permet d'ouvrir le test.
    Dans cet exemple, j'ai utilisé un seul test et un seul utilisateur dont peut importe le login et le mot de passe, juste pour l'exemple.
    2. Commencer le test (commencerTest.php) : où l'utilisateur choisi des thèmes et répond aux questions affichées puis valide pour aller sur la dernière page de validation.
    3. La validation du test (validerTest.php) qui enregistre les réponses de l'utilisateur dans la base et affiche son résultat.
Et voici les scripts des 3 pages qui sont reliées par une SESSION:

1. introduireAuTest.php
<?php
// La session utilisateur est activée
session_start();
		
// Identifier l'utilisateur		
if (isset($_POST["login"]) && isset($_POST["pwd"])){
	$user = chercherUser($_POST["login"], $_POST["pwd"]);
	if ($user != null){
		$_SESSION["idutilisateur"] = $user["id"];
		$_SESSION["nomutilisateur"] = $user["nom"];
		header("Location: commencerTest.php");
		exit();
	}
}
?>
<div id="divuser">
<form id="formuser" name="formuser" method="POST" action="">
<h1>Identifiez-vous pour commencer le test</h1>
<ul class="user">
<p><input type="text" id="login" name="login" value="" /></p>
<p><input type="password" id="pwd" name="pwd" value="" /></p>
</ul>
<input type="submit" value="Commencer le Test" />
<p>Veuillez saisir un login et un mot de passe valides.</p>
</form>
</div>

<?php
function chercherUser($login, $pwd){
	// à construire ...
	return array("id"=>"u1", "nom"=>"Dupont Jean"); // juste pour le test de ce programme
} 
?>
2. commencerTest.php
<?php
// La session utilisateur est activée
session_start();
// La base de données est ouverte
mysql_select_db("QCM", mysql_connect("localhost", "root"));

// L'utilisateur qui passe le test doit être déjà identifié dans un autre contexte
if (! isset($_SESSION["idutilisateur"])){
	// Non identifié s'abstenir !!
	echo "<p>Veuillez vous identifier avant de commencer le test!</p>";
	exit();
}
// Les thèmes du test doivent être sélectionnés par POST du formulaire ou existent déjà dans la SESSION
$liste_themes_coches = isset($_POST["liste_themes_coches"]) ? $_POST["liste_themes_coches"] 
: (isset($_SESSION["liste_themes_coches"]) ? $_SESSION["liste_themes_coches"] : null);
// Mettre à jour les thèmes mémorisés dans la SESSION
$_SESSION["liste_themes_coches"] = $liste_themes_coches;
// Afficher la liste des thèmes à cocher ou cochés si déjà fait (permet la modification des thèmes choisis)
$requete = "SELECT * FROM themes ORDER BY intitule";
$res = mysql_query($requete);
echo '<div id="divthemes">
<form id="formthemes" name="formthemes" method="POST" action="">
<h1>Liste des thèmes du test</h1>
<ul class="theme">';
while ($res && $themes = mysql_fetch_assoc($res)){
	// cocher les cases des thèmes déjà sélectionnés
	$case_cochee = "";
	if ($liste_themes_coches != null && isset($liste_themes_coches[$themes['id']])){
		$case_cochee = " checked=\"checked\" ";
	}
   echo '<input type="checkbox" name="liste_themes_coches['.$themes['id'].']" value="'.$themes['intitule'].'" '.$case_cochee.' />'.$themes['intitule'].'<br />';
}
echo '</ul>
<input type="submit" value="Sélectionnez les thèmes du test" />
<p>Veuillez sélectionner des thèmes du test!</p>
</form>
</div>';	

// Afficher les questions par thème sélectionné
if ($liste_themes_coches != null && is_array($liste_themes_coches)){
	echo '<div id="divtest">
	<form id="formtest" name="formtest" method="POST" action="validerTest.php">
	<h1>Questions</h1><ul class="theme">';
	foreach ($liste_themes_coches as $idtheme=>$intitule){
  		echo "<li>".$intitule."</li>\n";
    		$resaff=mysql_query("SELECT * FROM affirmations WHERE idtheme=".$idtheme);
    
    		echo '<ul class="affirmation">';
   		while ($affirmation = mysql_fetch_assoc($resaff)){
			// cocher les cases des thèmes déjà sélectionnés
			$case_cochee = "";
			if (isset($_POST["aff"]) && isset($_POST["aff"][$idtheme]) && in_array($affirmation['id'], $_POST["aff"][$idtheme])){
				$case_cochee = " checked=\"checked\" ";
			}
		        echo '<input type="checkbox" name="aff['.$idtheme.'][]" value="'.$affirmation['id'].'" '.$case_cochee.' />'.$affirmation['valeur'].' - '.$affirmation['points'].' point(s)<br />';
    		}
    		echo '</ul>';
	}
	echo '</ul>
	<input type="submit" value="Validez vos réponses" />
	</form>
	</div>';
}
?>
1. validerTest.php
<?php
// La session utilisateur est activée
session_start();
// La base de données est ouverte
mysql_select_db("QCM", mysql_connect("localhost", "root"));

// L'utilisateur qui passe le test doit être déjà identifié dans un autre contexte
if (! isset($_SESSION["idutilisateur"])){
	// Non identifié s'abstenir !!
	echo "<p>Veuillez vous identifier avant de commencer le test!</p>";
	exit();
}
// Les thèmes du test doivent être sélectionnés par POST du formulaire ou existent déjà dans la SESSION
$liste_themes_coches = isset($_POST["liste_themes_coches"]) ? $_POST["liste_themes_coches"] 
: (isset($_SESSION["liste_themes_coches"]) ? $_SESSION["liste_themes_coches"] : null);
// Mettre à jour les thèmes mémorisés dans la SESSION
$_SESSION["liste_themes_coches"] = $liste_themes_coches;
	

// Enregistrer et Afficher les réponses aux questions par thème sélectionné
if ($liste_themes_coches != null && is_array($liste_themes_coches)){
	echo '<div id="divtest">
	<h1>Réponses enregistrées</h1><ul class="theme">';
	$somme_points = 0;
	foreach ($liste_themes_coches as $idtheme=>$intitule){
  		echo "<li>".$intitule."</li>\n";

		if (isset($_POST["aff"]) && is_array($_POST["aff"][$idtheme])){
			foreach ($_POST["aff"][$idtheme] as $idaff){
				//On insère les resultats du test de la personne testee
				$reqteste = sprintf("INSERT INTO reponses (idutil, idaff)
						     VALUES ('%s', '%s')", $_SESSION['idutilisateur'], $idaff);
				mysql_query($reqteste);

    				$resaff=mysql_query("SELECT * FROM affirmations WHERE id=".$idaff);
    
    				echo '<ul class="affirmation">';
   				while ($affirmation = mysql_fetch_assoc($resaff)){
		        		echo '<li>'.$affirmation['valeur'].' - '.$affirmation['points'].' point(s)</li>';
					$somme_points += $affirmation['points'];
    				}
    				echo '</ul>';
			}
		}
	}
	echo '</ul>
	<h3>Vous avez ' . $somme_points . ' point(s)</h3>
	</div>';
}
?>
Bonne lecture :wink: