8797 sujets

Développement web côté serveur, CMS

Pages :
Bonjour,

Je tente actuellement de créer une page web qui permet de sélectionner un nombre de personnes et en fonction de ce nombre, des champs apparaitront en même quantité. Ces champs en question correspondent aux nom et prénom de ces personnes. Un exemple se trouve ici : http://testfred.chez.com/

Mon objectif est de rentrer les données dans une base, de retourner cette page avec les données de l'utilisateur et simultanément de m'envoyer un email pour m'avertir que quelqu'un à compléter le formulaire, et de pouvoir lire dans la base pour retourner les données d'un utilisateur à partir de son adresse email. Et que tout fonctionne sous Firefox, IE8, IE7 et IE6.

Comme vous pouvez le voir, la liste dynamique fonctionne (sous Firefox, je n'ai pas vérifié sous IE), mais je suis à présent bloqué pour entrer les données dans la base et faire fonctionner le bouton valider. Je précise que je souhaite éviter autant que possible le javascript.

Voici actuellement le code de la page :


<body>
<div id="corps">
	<h1>Confirmez votre présence</h1>
...
// si l'utilisateur soumet le formulaire on affiche la valeur de tous les champs du formulaire
if (isset($_POST['submit']) && $_POST['submit'] == "Valider")
{
	// on affiche le nombre de champs du formulaire
	echo 'Nombre d_accompagnants : '.$_POST['nb_accompagnants_formulaire'].'<br />';
	// on affiche la valeur des champs du formulaire
	for ($i=0; $i<=$_POST['nb_accompagnants_formulaire']; $i++)
	{
		$dynamique = 'nom_'.$i;
		$value = $_POST[$dynamique];
		echo 'Valeur du champ '.$i.' : '.$value.'<br />';
	}
}

// sinon on affiche le formulaire avec la possibilité d'ajout des champs au formulaire
else
{
	// on défini le nombre initial de champs
	if (!isset($_POST['nb_accompagnants_formulaire'])) // Test pour vérifier si les variables n'existent pas
	{
		$_POST['nb_accompagnants_formulaire'] = 0;
	}

	function choixParDefaut($nb_pers)			// Fonction permettant la conservation automatique du nombre de personnes lors de sa sélection dans le formulaire
	{
		$par_defaut = '';											// On crée une variable (vide par défaut) que l'on retournera à la fin
		if (isset($_POST['nb_accompagnants_formulaire']))				// Si le visiteur a choisi une valeur
		{
			if (<ital>$nb_pers</ital> == $_POST['nb_accompagnants_formulaire'])			// Si cette valeur correspond à la valeur que l'on est en train de traiter
			{
				$par_defaut='selected="selected"';					// Alors on modifie la variable que l'on retournera et on lui met selected
			}
		}
		return $par_defaut; // On ne retourne rien si ce n'était pas le nombre choisi, selected si c'était la bonne valeur
	}

...
	<form action="" method="post">
	<div class="bloc">
		<div class="cadre">
			<p style='padding-left: 20px;'>
				<input type="radio" name="participation" value="1" checked="checked" /> Sauf imprévu, nous confirmons notre venue
			</p>
			<p style='padding-left: 20px; padding-bottom: 15px;'>
				<input type="radio" name="participation" value="0" /> A notre plus grand regret, nous sommes dans l'incapacité d'être présents
			</p>
			<p>
				<br>
			</p>

			<p>
				Merci d'indiquer votre nom ci-dessous :
			</p>
			<p style='padding-left: 20px;'>
				<input type="text" name="prenom_0" value="  Votre prénom ici" />
			</p>
			<p style='padding-left: 20px; padding-bottom: 15px;'>
				<input type="text" name="nom_0" value="  Votre nom ici" />
			</p>
			<p>
				<br>
			</p>

			<p style='padding-bottom: 15px;'>Nombre de personnes vous accompagnant :
				<select name="nb_accompagnants_formulaire" onchange="submit();">		<!-- onchange="submit()" valid automatiquement le formulaire dès qu'une option select est choisie -->
					<option value="0" <?php echo choixParDefaut('0'); ?> >0</option>
					<option value="1" <?php echo choixParDefaut('1'); ?> >1</option>
					<option value="2" <?php echo choixParDefaut('2'); ?> >2</option>
					<option value="3" <?php echo choixParDefaut('3'); ?> >3</option>
					<option value="4" <?php echo choixParDefaut('4'); ?> >4</option>
					<option value="5" <?php echo choixParDefaut('5'); ?> >5</option>
					<option value="6" <?php echo choixParDefaut('6'); ?> >6</option>
					<option value="7" <?php echo choixParDefaut('7'); ?> >7</option>
					<option value="8" <?php echo choixParDefaut('8'); ?> >8</option>
					<option value="9" <?php echo choixParDefaut('9'); ?> >9</option>
					<option value="10" <?php echo choixParDefaut('10'); ?> >Plus</option>
				</select>
			</p>

			<?php
			for ($var = 0; $var <= $_POST['nb_accompagnants_formulaire']; $var++)
			{
				if ($var == 1)
				{
				?>
					<p>
						Précisez le nom des personnes concernées :
					</p>
				<?php
				}
				if ($var >= 1)
				{
				?>
					<p style='padding-left: 20px;'>
						<input type="text" name="prenom_'.$var.'" value="  Prénom" />
					</p>
					<p style='padding-left: 20px; padding-bottom: 15px;'>
						<input type="text" name="nom_'.$var.'" value="  Nom" />
					</p>
				<?php
				}
			}
			?>
		</div>

		<div class="cadre_droite">
			<p>
				Veuillez indiquer votre adresse e-mail ci-dessous pour pouvoir vous contacter.
			</p>
			<p>
				Si vous avez déjà complété ce formulaire, entrer votre adresse e-mail pour pouvoir modifier vos données ou votre sélection.
				<br><br>
			</p>
			<p style='padding-left: 0px; padding-bottom: 15px;'>
				<input type="text" name="email_1" />
				@ 
				<input type="text" name="email_2" />
			</p>

			<p>
				<br>
				Commentaires :
			</p>
			<p>
				<?php
				if ($_POST['nb_accompagnants_formulaire'] == "10")
				{
				?>
					Indiquez notamment les personnes supplémentaires présentes
				<?php
				}
				?>
			</p>
			<p>
				<textarea name="message" rows="8" cols="45"> Votre message ici.</textarea>
			</p>
		</div>
	</div>

	<div style='clear: left;'>					<!-- Supprime l'effet du flottant à gauche précédent -->
	</div>

	<p style='text-align:center;'>
		<input type="submit" value="Valider" />
	</p>
	</form>
<?php
}
?>

</body>



Pour faire fonctionner le bouton Valider, j'ai tenté de faire fonctionner le premier <gras>if</gras> en ajoutant une propriété name à input type="submit" sous la forme :
<input type="submit" name="submit" value="Valider" />
Mais dans ce cas, ma liste dynamique ne fonctionne plus et il est donc impossible d'entrer plus d'un nom et d'un prénom. Or sans cette possibilité, impossible d'entrer toutes les données dans la base, vu que l'utilisateur ne pourra pas toutes les entrer.
Avez-vous une solution à ce problèmre ?

Une autre question pour un problème qui risque de se poser bientôt : Comment puis-je faire pour que la validation du formulaire renvoie à la fois vers une page et m'envoie un email ?

Merci d'avance pour votre aide
Modifié par SkyCorp (02 May 2009 - 15:43)
Bonjour,

Avant tout est-ce que tu peux mettre les balises "code" autour de ton html, ce n'est pas très lisible et donc difficile de comprendre ton problème.
Hello SkyCorp et bienvenue Smiley smile ,

En tant que modérateur, je me dois de te faire remarquer que tu n'as malheureusement pas respecté l'une des Règles de base du forum qui est d'afficher les codes et exemples proprement à l'aide des boutons [ code]... ici ton code HTML, CSS, PHP, etc.[ /code] (sans espace après le crochet ouvrant).

upload/1-code.gif

Je te remercie par avance de bien vouloir éditer ton message afin de le rendre conforme à cette règle. Smiley cligne


En passant ton exemple de page est mal écrit car le JavaScript est "intrusif" (obstrusive in english) : dans un monde idéal où les pages seraient accessibles il faudrait pouvoir faire ce que tu souhaites en PHP pur et rajouter une surcouche JavaScript proprement (cf. Comment bien coder en Javascript).
Comme dit Heyoan l'idée ici serait plutôt d'afficher un formulaire pour une dizaine de personnes. Le javascript viendrait masquer les utilisateurs en trop.
Désolé pour l'oubli, il me semblait pourtant avoir mis les balises. Mon message a été édité à présent.

Sinon, je ne comprendss pas pourquoi vous me parlez de Javascript, vu que je souhaite éviter son emploi autant que possible (peut-être uniquement pour IE6 et versions inférieures). De plus, je n'utilise que du HTML et du PHP pour l'instant. Pouvez-vous me dire quel est le problème avec mon code ?
SkyCorp a écrit :
Sinon, je ne comprendss pas pourquoi vous me parlez de Javascript, vu que je souhaite éviter son emploi autant que possible
parce que onchange="..." c'est du JavaScript ! Smiley rolleyes
Ah d'accord, je ne savais pas. Y a-t-il alors moyen de conserver un aspect dynamique sans javascript ?
Ben non... mais il y a moyen de rajouter un INPUT submit à côté du sélecteur d'invités et de traiter cela en PHP.
C'est vrai, je n'y avais pas pensé. A présent mes 2 boutons fonctionnent, y compris le bouton Valider qui refusait de fonctionner auparavant. Smiley smile

Mais je viens de rencontrer un nouveau problème (cf mon site que j'ai mis à jour).
Lorsque je valide le formulaire, nom_0 s'affiche bien. Mais pas les autres noms, issus de ma boucle for. Une idée pour résoudre ce problème ? Y a-t-il un problème avec name="nom_'.$var.'" dans <input type="text" name="nom_'.$var.'" value=" Nom" /> ?
Salut,

le plus simple est d'utiliser un array pour le nom de tes INPUT :
<!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>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>
</head>
<body>
<?php
if($_SERVER['REQUEST_METHOD']=='POST') {
	$prenom = !empty($_POST['prenom']) ? $_POST['prenom'] : array();
	$nom = !empty($_POST['nom']) ? $_POST['nom'] : array();
	for($i = 0; $i < count($prenom); $i++) {
		echo '<p>Prénom : '.$prenom[$i].' / Nom : '.$nom[$i].'</p>';
	}
}
?>
<form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
	<p>
		<label for="prenom_1">Prénom :</label>
		<input type="text" name="prenom[]" id="prenom_1" />
	</p>
	<p>
		<label for="nom_1">Nom :</label>
		<input type="text" name="nom[]" id="nom_1" />
	</p>
	<p>
		<label for="prenom_2">Prénom :</label>
		<input type="text" name="prenom[]" id="prenom_2" />
	</p>
	<p>
		<label for="nom_2">Nom :</label>
		<input type="text" name="nom[]" id="nom_2" />
	</p>
	<p>
		<label for="prenom_3">Prénom :</label>
		<input type="text" name="prenom[]" id="prenom_3" />
	</p>
	<p>
		<label for="nom_3">Nom :</label>
		<input type="text" name="nom[]" id="nom_3" />
	</p>
	<p>
		<input type="submit" />
	</p>
</form>
</body>
</html>

Modifié par Heyoan (28 Apr 2009 - 11:40)
Je viens de tenter ta méthode en l'adaptant un peu et tout fonctionne Smiley smile . Merci pour tout!

J'avais tenté d'utiliser un array lorsque j'ai débuté la création de cette page, mais sans succès. Mais je ne suis pas encore familier avec certaines de ces expressions, notamment $prenom = !empty($_POST['prenom']) ? $_POST['prenom'] : array(); ou la variable $_SERVER['REQUEST_METHOD'], les différents tutoriaux que j'ai abordés ne les mentionnant pas. Connais-tu un bon site qui explique ça ?
Je ne sais pas non plus ce qui posait problème avant. J'avais trouvé la partie correspondant à la définition de la variable à problème sur le web et adapté à mon cas, mais le code semblait logique et je ne comprend pas trop d'où vient l'erreur. Une idée ?
Modifié par SkyCorp (29 Apr 2009 - 07:49)
SkyCorp a écrit :
Mais je ne suis pas encore familier avec certaines de ces expressions, notamment $prenom = !empty($_POST['prenom']) ? $_POST['prenom'] : array();
Il s'agit de l'opérateur ternaire.

SkyCorp a écrit :
ou la variable $_SERVER['REQUEST_METHOD']
Lire : les Superglobales.

SkyCorp a écrit :
Je ne sais pas non plus ce qui posait problème avant...
Eh bien en regardant la page en ligne je vois :
<input type="text" name="prenom_'.$var.'" value="  PrÚnom" />
...
<input type="text" name="nom_'.$var.'" value="  Nom" />
ce qui veut dire que ton code PHP n'est pas interprété (en général cela vient d'une incompréhension des règles de concaténation et des différences entre quotes et guillemets) : lire Essentiel sur les variables.


Pour finir, et puisqu'on est sur Alsa, ton code en ligne est invalide et pour des raisons d'accessibilité et d'ergonomie il faudrait associer chaque INPUT à un LABEL (comme dans mon exemple précédent). Smiley cligne
Merci pour tes explications, je vais peut-être poursuivre ma formation PHP sur ce site, apparemment bien plus complet que les tutoriaux que j'ai pu trouver.

Heyoan a écrit :
Pour finir, et puisqu'on est sur Alsa, ton code en ligne est invalide et pour des raisons d'accessibilité et d'ergonomie il faudrait associer chaque INPUT à un LABEL (comme dans mon exemple précédent). Smiley cligne

J'ai testé ma page test que j'avais modifié hier et je n'ai trouvé que des erreurs sur <br> (une mauvaise habitude). Une fois cette erreur corrigée, mon code a été validé sans utilisation de LABEL. Mais il me semblait que l'un des objectifs du W3C était justement l'accessibilité. Le validateur ne prend-t-il pas ça en compte ?
SkyCorp a écrit :
mon code a été validé sans utilisation de LABEL. Mais il me semblait que l'un des objectifs du W3C était justement l'accessibilité. Le validateur ne prend-t-il pas ça en compte ?
Eh non : ce n'est qu'un outil de "premier niveau" qui ne fait que vérifier que le code (en fonction du doctype choisi) est valide. C'est essentiel mais cela n'assure absolument pas qu'une page soit accessible.

Pour aller plus loin tu peux lire cet article (Wikipédia).

PS: si tu considères que ce sujet est [Résolu] merci de l'indiquer en éditant ton premier post et en modifiant le titre. Smiley cligne
Modifié par Heyoan (30 Apr 2009 - 00:39)
Je sens qu'il me reste encore beaucoup à apprendre !

Avant de conclure ce sujet, j'ai une dernière question de sécurité sur laquelle j'ai commencé à faire quelques recherches mais encore sans résultat.

Je cherche à sécuriser les champs du formulaire, pour éviter tout problème créé par un visiteur indésirable. Pour les champs uniques, je pensais faire quelque chose du style $message = mysql_real_escape_string(htmlspecialchars($_POST['message'])); mais aucune idée pour les variables issus de ma boucle for (les champs nom et prénom que l'on a traité juste avant). J'ai tout d'abord tenté de l'utiliser dans $prenom = !empty($_POST['prenom']) ? $_POST['prenom'] : array(); (que j'ai transformé en $prenom = !empty(mysql_real_escape_string(htmlspecialchars($_POST['prenom']))) ? mysql_real_escape_string(htmlspecialchars($_POST['prenom'])) : array();)
mais cette ligne me retourne l'erreur suivante : Fatal error: Can't use function return value in write context in ... on line 82.
Et si je crée une varible intermédiaire : $prenom_formulaire = mysql_real_escape_string(htmlspecialchars($prenom)); et que l'ECHO porte sur $prenom_formulaire, voilà l'erreur retourné :Warning: htmlspecialchars() expects parameter 1 to be string, array given in ... on line 86 (la ligne correspondante à la variable intermédiaire) et Notice: Uninitialized string offset: 0 in ... on line 91 (la ligne correspondant à l'affichage des variables).
D'autres erreurs apparaissent aussi mais sans doute liées à celles-là.

Y a-t-il un moyen de sécuriser d'avantage ma page ? Je tiens à préciser que les données sont tout de même sauvées dans la base.

Une dernière question au passage : je cherche également à envoyer la réponse des utilisateurs par email (en plus de sauvegarder les données dans la base et afficher des infos à l'utilisateur sur la même page, donc sans modifier le <form action="<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">. J'ai commencé à trouver des infos sur le web, mais une aide serait la bienvenue.

Merci d'avance!
Modifié par SkyCorp (30 Apr 2009 - 08:23)
Désolé, je dois être un peu fatigué, mais j'ai jeté un coup d'oeil à ces liens et je n'ai pas trouvé de solution à ma question sur la sécurité.
D'après ce que j'ai lu sur ton lien et ici, mysql_real_escape_string sert notamment à éviter d'introduire du code SQL dans la base. D'où l'intérêt d'utiliser cette fonction et htmlspecialchars() ensemble avant d'écrire les données dans la base.
Mais ça ne m'aide pas à savoir comment les utiliser avec les champs 'nom' et 'prénom', et une petite aide serait la bienvenue.

Concernant l'envoi des données par mail, j'ai trouvé des infos à ce sujet. Combinées au lien que tu m'as fournies, je devrais pouvoir m'en sortir. Je m'en occuperai à tête reposé après une bonne nuit de sommeil.
SkyCorp a écrit :
D'après ce que j'ai lu sur ton lien et ici, mysql_real_escape_string sert notamment à éviter d'introduire du code SQL dans la base.
On parle d'injection SQL (et cela n'a rien à voir avec "introduire du code SQL dans la base").

SkyCorp a écrit :
D'où l'intérêt d'utiliser cette fonction et htmlspecialchars() ensemble avant d'écrire les données dans la base.
Non : encore une fois htmlspecialchars ne sert qu'au moment d'un affichage html donc il est inutile de l'utiliser avant sauvegarde.

SkyCorp a écrit :
Mais ça ne m'aide pas à savoir comment les utiliser avec les champs 'nom' et 'prénom', et une petite aide serait la bienvenue.
Les liens que je t'ai donnés sont pourtant bien fournis en exemples... Smiley rolleyes
L'inconvénient avec ce site, c'est qu'en dehors des exemples donnés par le rédacteur du descriptif de la propriété, il est difficile de s'y retrouver dans les exemples donnés en commentaire par les internautes (il y a beaucoup d'exemples je l'admets, mais peut-être un peu trop), d'autant plus que les exemples ne sont pas toujours corrects vu que des correctifs sont parfois apportés, et les explications sont pour le moins très succinctes. Une synthèse aurais été la bienvenue.

Bref après plusieurs heures de lecture, j'ai trouvé plusieurs exemples pour htmlspecialchars qui pourraient correspondre à ce que je cherche (mais sans certitude). Voici les codes en question :
function formspecialchars($var)
{
	if (is_array($var))
	{
		$out = array();
		foreach ($var as $key => $v)
		{
			$out[$key] = formspecialchars($v);
		}
	} else
	{
		$out = htmlspecialchars_decode($var);
		$out = htmlspecialchars(stripslashes(trim($out)), ENT_QUOTES);
	}
	return $out;
}

function reverse_htmlentities($mixed)
{
    $htmltable = get_html_translation_table(HTML_ENTITIES);
    foreach($htmltable as $key => $value)
    {
        $mixed = ereg_replace(addslashes($value),$key,$mixed);
    }
    return $mixed;
}


function HTML_ESC($_input = null, $_esc_keys = false)
{
    if ((null != $_input) && (is_array($_input)))
    {
        foreach($_input as $key => $value)
        {
            if($_esc_keys)
            {
                $_return[htmlspecialchars($key)] = HTML_ESC($value,$_esc_keys);
            }
            else
            {
                $_return[$key] = HTML_ESC($value);
            }
        }
        return $_return;
    }
    elseif(null != $_input)
    {
        return htmlspecialchars($_input);
    }
    else
    {
        return null;
    }
}

et
function htmlspecialchars_array($arr = array())
{
   $rs =  array();
   while(list($key,$val) = each($arr))
   {
       if(is_array($val))
	   {
           $rs[$key] = htmlspecialchars_array($val);
       }
       else
	   {
           $rs[$key] = htmlspecialchars($val, ENT_QUOTES);
       }   
   }
   return $rs;
}

Reste maintenant à voir laquelle est la plus appropriée (personnellement, je penche pour la première fonction, mais ce n'est peut-être pas la meilleure)

Heyoan a écrit :
Non : encore une fois htmlspecialchars ne sert qu'au moment d'un affichage html donc il est inutile de l'utiliser avant sauvegarde.

Si j'ai bien compris, htmlspecialchars convertit certains caractères afin d'éviter de retrouver du code HTML provenant du formulaire, ce qui peut effectivement poser problème lors de l'affichage des données. Mais pourquoi ne pas convertir ces caractères au moment de la sauvegarde des données dans la base, par exemple dans le cas d'une base par la suite libre d'accès (ce n'est pas la cas ici, mais je compte m'attaquer à un autre site un peu plus tard) ? Cela devrait éviter de se préoccuper de ce point plus tard, lors de l'affichage par exemple, non ?

Concernant mysql_real_escape_string, tu avais dit plus tôt :
Heyoan a écrit :
mysql_real_escape_string ne sert qu'à protéger les données au moment de les insérer dans la base.
C'est un peu le but, sécuriser les requêtes et éviter que quelqu'un ne s'introduise dans la base et ne manipule les données. Je me suis un peu embrouillé l'esprit hier c'est vrai, mais c'est bien l'intérêt de la manip il me semble.

J'espère que je suis suffisamment clair en tout cas et que je ne m'embrouille pas trop. Mais j'ai l'impression d'être quasiment au même point qu'avant, trouver la meilleure façon d'améliorer la sécurité de mon site. Dois-je utiliser la première fonction que j'ai présentée pour htmlspecialchars ? Est-il encore utile de tenter d'utiliser mysql_real_escape_string et si oui, comment (vu que ça n'avais pas l'air de fonctionner auparavant) ?
J'espère ne pas être trop insistant, mais c'est la dernière étape avant la mise en place de ma page sur Internet, qui est sensée être terminée aujourd'hui, et je voudrais qu'elle soit parfaite tout en comprenant ce que je fais.
SkyCorp a écrit :
...et je voudrais qu'elle soit parfaite tout en comprenant ce que je fais.
Ben le mieux pour comprendre est de ne reprendre du code que lorsqu'on comprend ce qu'il fait. Smiley cligne

Bon alors pouf pouf !

1) réception d'une variable soumise :
$prenom = !empty($_POST['prenom']) ? $_POST['prenom'] : '';

2) insertion en base :
$sql = 'insert into ma_table (prenom) values (' . mysql_real_escape_string($prenom) . ')';

3) affichage html (ou mail) :
echo '<p>Prénom : ' . htmlspecialchars($prenom) . '</p>';


Pour ce qui est de ne pas faire le htmlspecialchars avant sauvegarde je vois au moins 2 raisons :
1) cela permet de comprendre à quoi sert cette fonction.
2) les chaînes de caractères sont plus longues après avoir subi cette fonction et ce n'est pas logique de stocker plus de caractères que nécessaire.

Bien sûr il n'y a pas mort d'homme si tu décides de le faire quand même...
Modifié par Heyoan (01 May 2009 - 17:23)
Pages :