8721 sujets

Développement web côté serveur, CMS

Bonsoir,

Je tente d'ajouter un formulaire d'inscription au site que je suis en train de créer (en local pour l'instant).

Ma page fonctionne, mais je ne suis pas sûr de m'y prendre correctement pour insérer les données du formulaire dans la base de données. J'utilise MySql version 5.1.

Voici le code de ma page :
<?php $state = ""; $err = "";
if (isset($_POST["subscribe"])) {
	$state = "error";
	if (isset($_POST["name"])) { $_POST["name"] = trim(stripslashes($_POST["name"])); }
	if (isset($_POST["firstname"])) { $_POST["firstname"] = trim(stripslashes($_POST["firstname"])); }
	if (isset($_POST["public_id"])) { $_POST["public_id"] = trim(stripslashes($_POST["public_id"])); }
	if (isset($_POST["email"])) { $_POST["email"] = trim(stripslashes($_POST["email"])); }
	if (isset($_POST["pwd"])) { $_POST["pwd"] = trim(stripslashes($_POST["pwd"])); }
	if (empty($_POST["name"])) { $err = "Le nom est obligatoire."; }
	elseif (empty($_POST["firstname"])) { $err = "Le prénom est obligatoire."; }
	elseif (empty($_POST["public_id"])) { $err = "L'identifiant public est obligatoire."; }
	elseif (empty($_POST["email"])) { $err = "L'adresse email est obligatoire."; }
	elseif (!eregi("^[0-9a-z][-_.0-9\+a-z]*@[0-9a-z][a-z0-9_-]*\.([a-z0-9_-]+\.)*[a-z]{2,}$", $_POST["email"])) { $err = "L'adresse email indiquée n'est pas valide."; }
	elseif (empty($_POST["confirm_email"])) { $err = "La confirmation de l'adresse email est obligatoire."; }
	elseif ($_POST["email"] != $_POST["confirm_email"]) { $err = "L'adresse email confirmée n'est pas correcte."; }
	elseif (empty($_POST["pwd"])) { $err = "Le mot de passe est obligatoire."; }
	elseif (strlen($_POST["pwd"]) < 5) { $err = "Le mot de passe doit compter au minimum 5 caractères."; }
	else {	$state = "ok"; }
} ?>
<form action="inscription.php" method="post" >
	<fieldset>
		<legend>Formulaire d'inscription</legend>
		<?php if ($state == "error") {
			echo '<p class="error">Erreur :<br />'.$err."</p>";
		} ?>
		<p><b>Tous les champs sont obligatoires.</b></p>
		<div class="form-field text">
			<label for="nom">Votre nom :</label>
			<input type="text" name="name" id="nom" size="20" maxlength="40" value="<?php if (!empty($_POST["name"])) { echo htmlspecialchars($_POST["name"],ENT_QUOTES); } ?>" />
			<p class="input-comment">Votre nom ne sera pas affiché.</p>
		</div>
		<div class="form-field text">
			<label for="prenom">Votre prénom :</label>
			<input type="text" name="firstname" id="prenom" size="20" maxlength="40" value="<?php if (!empty($_POST["firstname"])) { echo htmlspecialchars($_POST["firstname"],ENT_QUOTES); } ?>" />
			<p class="input-comment">Votre prénom ne sera pas affiché.</p>
		</div>
		<div class="form-field text">
			<label for="identifiant">Votre identifiant public :</label>
			<input type="text" name="public_id" id="identifiant" size="20" maxlength="40" value="<?php if (!empty($_POST["public_id"])) { echo htmlspecialchars($_POST["public_id"],ENT_QUOTES); } ?>" />
		</div>
		<div class="form-field text">
			<label for="email">Votre adresse e-mail :</label>
			<input type="text" name="email" id="email" size="20" maxlength="40" value="<?php if (!empty($_POST["email"])) { echo htmlspecialchars($_POST["email"],ENT_QUOTES); } ?>" />
		</div>
		<div class="form-field text">
			<label for="confirme-email">Confirmez votre adresse e-mail :</label>
			<input type="text" name="confirm_email" id="confirme-email" size="20" maxlength="40" value="<?php if (!empty($_POST["confirm_email"])) { echo htmlspecialchars($_POST["confirm_email"],ENT_QUOTES); } ?>" />
		</div>
		<div class="form-field checkbox">
			<input type="checkbox" name="autorise-email" id="autorise-email" />
			<label for="autorise-email">Autoriser les contacts par e-mail</label>
		</div>
		<div class="form-field password">
			<label for="motdepasse">Votre mot de passe :</label>
			<input type="password" name="pwd" id="motdepasse" size="20" maxlength="40" value="<?php if (!empty($_POST["pwd"])) { echo htmlspecialchars($_POST["pwd"],ENT_QUOTES); } ?>" />
			<p class="input-comment">Votre mot de passe doit compter au minimum 5 caractères.</p>
		</div>
		<div>
			<input type="submit" name="subscribe" class="button" value="Inscription" />
		</div>
	</fieldset>
</form>

<?php if ($state == "ok") {
require 'config.php';

mysql_connect("$hostname", "$dbuser","$dbpassword");
mysql_select_db("$dbname") OR die("ERREUR de connexion : ".mysql_error());
if (isset($_POST["autorise_email"])) { $autmail = 1; } else { $autmail = 0; }
$sql = mysql_query('INSERT INTO `users` VALUES ("'.$_POST['name'].'", "'.$_POST['firstname'].'", "'.$_POST['public_id'].'", "'.$_POST['email'].'", "'.$autmail.'", "'.$_POST['pwd'].'"); ');

if (!$sql) { die ('Erreur de requête : '.mysql_error()); } else { echo 'Les données ont bien été enregistrées.'; }
mysql_close();
} ?>

J'ai donc quelques questions :

1. Est-ce que cette manière de faire ne présente pas de failles de sécurité ?
2. Présente-t-elle des soucis particuliers de lenteur ou autres ?
3. Les caractères spéciaux (accentués par exemple) ne semblent pas être correctement inscrits dans la base de données. J'ai "François" au lieu de "François" dans une colonne "prénom" pourtant créée en utf-8. Comment résoudre cela ?

Merci d'avance pour votre aide !
Modifié par Fix (13 Oct 2013 - 18:34)
Commence déjà par me transformer tous ces mysql_ en mysqli_ (le lien en signature t'expliquera comment faire ça proprement)... Mysql_ est une extension dépréciée depuis un petit temps et obsolète depuis peu.

Ensuite, j'ai passé en gros (l'est tard), mais déjà pour le email -et pas mal d'autres champs- va faire un tour du coté des Filter_var.
Merci beaucoup pour ton aide !

J'ai donc remplacé mon code pour valider l'adresse email de la manière suivante :
if (isset($_POST["email"])) { $_POST["email"] = filter_var($_POST["email"], FILTER_VALIDATE_EMAIL); }
...
elseif (!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL)) { $err = "L'adresse email indiquée n'est pas valide."; }


Comment puis-je valider les autres champs ? (pas de balise html ni de caractère exotique pour les noms et prénoms, par exemple...)

Pour ce qui est de la connexion à la BDD, voici ce que ça donne (un grand merci pour ton lien très clair et facile à suivre) :
$link = mysqli_connect("$hostname", "$dbuser","$dbpassword","$dbname");
if (isset($_POST["autorise_email"])) { $autmail = 1; } else { $autmail = 0; }
$sql = mysqli_query($link, 'INSERT INTO `users` VALUES ("'.$_POST['name'].'", "'.$_POST['firstname'].'", "'.$_POST['public_id'].'", "'.$_POST['email'].'", "'.$autmail.'", "'.$_POST['pwd'].'"); ');

if (!$sql) { die ('Erreur de requête : '.mysqli_error($link)); } else { echo 'Les données ont bien été enregistrées.'; }
mysqli_close($link);

D'autres améliorations peuvent-elles y être apportées ? Y a-t-il moyen d'éviter, par exemple, l'injection de code ? (via l'url il me semble, comme je l'ai lu sur certains sites... sans comprendre parfaitement, malheureusement)
Modifié par Fix (13 Oct 2013 - 08:33)
Les filtres de nettoyage sont déjà pas mal Filtres de nettoyage

FILTER_SANITIZE_FULL_SPECIAL_CHARS Celui-ci est pas mal pour les chaînes alpha-numériques

FILTER_SANITIZE_NUMBER_INT pour les données chiffrées

ctype-alpha peut te permettre de vérifier si y a uniquement des lettres (faire gaffe, je ne sais pas comment ça réagit en fonction des encodages)
D'accord. Donc, si je comprends bien, il ne fallait pas :
if (isset($_POST["email"])) { $_POST["email"] = filter_var($_POST["email"], FILTER_VALIDATE_EMAIL); }

mais
if (isset($_POST["email"])) { $_POST["email"] = filter_var($_POST["email"], FILTER_SANITIZE_EMAIL); }

C'est bien cela ?

Du coup, je peux remplacer :
if (isset($_POST["name"])) { $_POST["name"] = trim(stripslashes($_POST["name"])); }
(ainsi que toutes les lignes du même genre)

par :
if (isset($_POST["name"])) { $_POST["name"] =filter_var($_POST["name"], FILTER_SANITIZE_FULL_SPECIAL_CHARS); }

J'ai bon ?
filter_validate_email sert si tu veux faire un message d'erreur genre :

if(!empty($_POST['email'])
{
     if(!filter_var($_POST["email"], FILTER_VALIDATE_EMAIL))
     {
            $erreur['mail']="Le email n'est pas valide";
     }
}
else
{
    $erreur['mail']="Le champs email est obligatoire";
}


filter_sanitize_mail permet de transformer ton string dans un truc qui pourrait être un email (ou à défaut qui n'a pas de caractères interdits).


Et pour le second oui ^^ et tu peux tester avec ctype pour avertir les gens qu'ils ont écrits n'importe quoi.