On arrive à une partie un peu plus difficile, non pas parce qu'elle demande des connaissances particulières, mais parce que le code de ces deux pages va être plus long. Mais pas de panique : ce n'est pas ça qui va nous effrayer, hein ?

Allez : on commence !
Formulaire
Comme pour le système de connexion, on va diviser la page en deux parties: une pour le formulaire, et l'autre pour le traitement des données envoyées. Pour le nom, je n'ai rien trouvé de plus glamour que
register.php on va faire avec pour l'instant

.
Comme tout à l'heure, la partie formulaire est vraiment simple et courte, voyons d'abord le début :
Page : register.php
Code : PHP | <?php
session_start();
$titre="Enregistrement";
include("includes/identifiants.php");
include("includes/debut.php");
include("includes/menu.php");
echo '<p><i>Vous êtes ici</i> : <a href="./index.php">Index du forum</a> --> Enregistrement';
if ($id!=0) erreur(ERR_IS_CO);
?>
|
Vous voyez qu'on retrouve la fonction
erreur, on commence à en voir l'utilité, c'est quand même plus rapide que de se farcir le bloc if/then/else plus le message à chaque fois.
On continue avec l'affichage du formulaire :
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 | <?php
if (empty($_POST['pseudo'])) // Si on la variable est vide, on peut considérer qu'on est sur la page de formulaire
{
echo '<h1>Inscription 1/2</h1>';
echo '<form method="post" action="register.php" enctype="multipart/form-data">
<fieldset><legend>Identifiants</legend>
<label for="pseudo">* Pseudo :</label> <input name="pseudo" type="text" id="pseudo" /> (le pseudo doit contenir entre 3 et 15 caractères)<br />
<label for="password">* Mot de Passe :</label><input type="password" name="password" id="password" /><br />
<label for="confirm">* Confirmer le mot de passe :</label><input type="password" name="confirm" id="confirm" />
</fieldset>
<fieldset><legend>Contacts</legend>
<label for="email">* Votre adresse Mail :</label><input type="text" name="email" id="email" /><br />
<label for="msn">Votre adresse MSN :</label><input type="text" name="msn" id="msn" /><br />
<label for="website">Votre site web :</label><input type="text" name="website" id="website" />
</fieldset>
<fieldset><legend>Informations supplémentaires</legend>
<label for="localisation">Localisation :</label><input type="text" name="localisation" id="localisation" />
</fieldset>
<fieldset><legend>Profil sur le forum</legend>
<label for="avatar">Choisissez votre avatar :</label><input type="file" name="avatar" id="avatar" />(Taille max : 10Ko<br />
<label for="signature">Signature :</label><textarea cols="40" rows="4" name="signature" id="signature">La signature est limitée à 200 caractères</textarea>
</fieldset>
<p>Les champs précédés d un * sont obligatoires</p>
<p><input type="submit" value="S\'inscrire" /></p></form>
</div>
</body>
</html>';
} //Fin de la partie formulaire
?>
|
Analysons un peu ce code. Tout à l'heure on s'est assuré que l'utilisateur était bien un simple visiteur, ensuite il faut regarder si on est dans le cas de l'affichage du formulaire ou dans le cas du traitement, pour cela on s'intéresse à la variable
$_POST['pseudo']. A priori, si celle-ci est vide, c'est qu'on vient d'arriver sur la page (à moins que le visiteur n'est oublié de renseigner son pseudo ce qui est assez étrange vous me le concèderez...). Si tout va bien, on lance le formulaire avec plusieurs champs à remplir (le nombre des champs et ce que vous voulez en faire dépend totalement de votre table
forum_membres ; si vous voulez par exemple demander l'âge du membre, pensez à créer un champ
membre_age avant).
Dis-moi bonhomme, pourquoi tu as rajouté enctype="multipart/form-data" dans ta balise <form> ?
C'est une bonne question... à laquelle je ne vais pas répondre. Non pas par flemme (encore que...), mais parce qu'un tutoriel rédigé par DHKold l'a déjà fait (et sûrement mieux que je ne le ferais). De toute façon, il vous faudra le lire si vous voulez comprendre la suite. Ce tutoriel traite des uploads de fichiers (
lien), et on va s'en servir pour les avatars.
Bon. Si vous êtes toujours là, on va pouvoir s'attaquer à la deuxième partie de la page

!
Traitement
Exactement comme pour la page connexion.php, on va réaliser une série de tests pour voir si tout concorde. Si ce n'est pas le cas, on affiche un message d'erreur. Mais contrairement au système de connexion, on n'a plus que trois champs à vérifier.
Page : register.php
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 | <?php
else //On est dans le cas traitement
{
$pseudo_erreur1 = NULL;
$pseudo_erreur2 = NULL;
$mdp_erreur = NULL;
$email_erreur1 = NULL;
$email_erreur2 = NULL;
$msn_erreur = NULL;
$signature_erreur = NULL;
$avatar_erreur = NULL;
$avatar_erreur1 = NULL;
$avatar_erreur2 = NULL;
$avatar_erreur3 = NULL;
?>
|
On n'oublie pas de déclarer nos variables au début, chez certains ça n'est pas nécessaire mais chez d'autres ça fait tout planter donc autant le faire.
Pseudo et mot de passe
Pour la suite, on va commencer par vérifier les champs pseudo et mot de passe : ce sont les deux qui demandent le plus de tests.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 | <?php
//On récupère les variables
$i = 0;
$temps = time();
$pseudo=$_POST['pseudo'];
$signature = $_POST['signature'];
$email = $_POST['email'];
$msn = $_POST['msn'];
$website = $_POST['website'];
$localisation = $_POST['localisation'];
$pass = md5($_POST['password']);
$confirm = md5($_POST['confirm']);
//Vérification du pseudo
$query=$db->prepare('SELECT COUNT(*) AS nbr FROM forum_membres WHERE membre_pseudo =:pseudo');
$query->bindValue(':pseudo',$pseudo, PDO::PARAM_STR);
$query->execute();
$pseudo_free=($query->fetchColumn()==0)?1:0;
$query->CloseCursor();
if(!$pseudo_free)
{
$pseudo_erreur1 = "Votre pseudo est déjà utilisé par un membre";
$i++;
}
if (strlen($pseudo) < 3 || strlen($pseudo) > 15)
{
$pseudo_erreur2 = "Votre pseudo est soit trop grand, soit trop petit";
$i++;
}
//Vérification du mdp
if ($pass != $confirm || empty($confirm) || empty($pass))
{
$mdp_erreur = "Votre mot de passe et votre confirmation diffèrent, ou sont vides";
$i++;
}
?>
|
Voilà, on est arrivés au bout. Je vais détailler ce qui est écrit plus haut.
Pour commencer, j'initialise une variable
$i à 0 : son rôle est de stocker le nombre d'erreurs. Pour ce faire, elle est incrémentée à chaque fois qu'un problème est détecté.
Ensuite on passe au pseudo. Il y a plusieurs erreurs possibles : soit le pseudo existe déjà, dans ce cas, on fait une requête qui va nous retourner le nombre d'entrées de la table
forum_membres ayant le même pseudo que celui qui a été posté. Pour cela j'utilise une 4 lignes de code qui vous ont peut être posé un peu de soucis.
Code : PHP | <?php
$query=$db->prepare('SELECT COUNT(*) AS nbr FROM forum_membres WHERE membre_pseudo =:pseudo');
$query->bindValue(':pseudo',$pseudo, PDO::PARAM_STR);
$query->execute();
$pseudo_free=($query->fetchColumn()==0)?1:0;
?>
|
Bon pour les trois premières je pense que ça va, ce n'est qu'une simple requête tout ce qu'il y a de plus inoffensif. Pour la dernière, j'utilise la méthode
fetchColumn() de l'objet
$query qui va récupérer le nombre d'entrées correspondant à la requête.
Si celle-ci est 0, tout va bien et la variable booléenne
$pseudo_free sera mise à vraie (ou 1, le pseudo n'est pas déjà utilisé). Sinon elle vaudra 0 (le pseudo est déjà utilisé). Dans ce dernier cas, il y a un problème : donc, on incrémente
$i.
Par ailleurs, vous avez pu remarquer la présence de la variable
$message_pseudo1 : elle va stocker un message, qu'on affichera plus tard pour aider le membre à corriger ses erreurs.
Bref, continuons : la deuxième erreur concerne la taille du pseudo. En général, on aime qu'il contienne entre 3 et 15 caractères (ne me demandez pas pourquoi, par contre

) : donc j'ai utilisé la fonction
strlen qui retourne le nombre de caractères d'un texte. Encore une fois, s'il y a un problème, on incrémente
$i, et on crée le message.
On arrive maintenant au mot de passe. Pour lui, on a fait d'une pierre deux coups, puisque j'ai vérifié en même temps s'il était identique à la confirmation, et s'il était vide.
e-mail, MSN et Signature
Sans plus attendre, la suite du code

:
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 | <?php
//Vérification de l'adresse email
//Il faut que l'adresse email n'ait jamais été utilisée
$query=$db->prepare('SELECT COUNT(*) AS nbr FROM forum_membres WHERE membre_email =:mail');
$query->bindValue(':mail',$email, PDO::PARAM_STR);
$query->execute();
$mail_free=($query->fetchColumn()==0)?1:0;
$query->CloseCursor();
if(!$mail_free)
{
$email_erreur1 = "Votre adresse email est déjà utilisée par un membre";
$i++;
}
//On vérifie la forme maintenant
if (!preg_match("#^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]{2,}\.[a-z]{2,4}$#", $email) || empty($email))
{
$email_erreur2 = "Votre adresse E-Mail n'a pas un format valide";
$i++;
}
//Vérification de l'adresse MSN
if (!preg_match("#^[a-zA-Z0-9._-]+@[a-zA-Z0-9._-]{2,}\.[a-z]{2,4}$#", $msn) && !empty($msn))
{
$msn_erreur = "Votre adresse MSN n'a pas un format valide";
$i++;
}
//Vérification de la signature
if (strlen($signature) > 200)
{
$signature_erreur = "Votre signature est trop longue";
$i++;
}
?>
|
On fait des vérifications sur les adresses e-mail et MSN, qui utilisent les
regex, afin d'être sûrs que le visiteur n'a pas entré n'importe quoi.
Remarquez que la
regex utilisée pour l'adresse MSN peut être différente si on veut être plus précis et certains qu'elle est bien en .hotmail ou .msn...
En revanche pour la signature, on n'a pas ce genre de problème : on vérifie alors juste la longueur avec la fonction
strlen ; par ailleurs, comme le champ n'était pas obligatoire, il est inutile de vérifier s'il est vide.
L'avatar
On va s'arrêter un petit moment sur l'avatar, car c'est ce qui demande le plus de vérifications. Vous pouvez facilement comprendre pourquoi on ne peut pas laisser des inconnus envoyer n'importe quoi sur notre serveur. Le tuto que j'ai mentionné plus haut explique ceci en détail.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36 | <?php
//Vérification de l'avatar :
if (!empty($_FILES['avatar']['size']))
{
//On définit les variables :
$maxsize = 10024; //Poid de l'image
$maxwidth = 100; //Largeur de l'image
$maxheight = 100; //Longueur de l'image
$extensions_valides = array( 'jpg' , 'jpeg' , 'gif' , 'png', 'bmp' ); //Liste des extensions valides
if ($_FILES['avatar']['error'] > 0)
{
$avatar_erreur = "Erreur lors du transfert de l'avatar : ";
}
if ($_FILES['avatar']['size'] > $maxsize)
{
$i++;
$avatar_erreur1 = "Le fichier est trop gros : (<strong>".$_FILES['avatar']['size']." Octets</strong> contre <strong>".$maxsize." Octets</strong>)";
}
$image_sizes = getimagesize($_FILES['avatar']['tmp_name']);
if ($image_sizes[0] > $maxwidth OR $image_sizes[1] > $maxheight)
{
$i++;
$avatar_erreur2 = "Image trop large ou trop longue :
(<strong>".$image_sizes[0]."x".$image_sizes[1]."</strong> contre <strong>".$maxwidth."x".$maxheight."</strong>)";
}
$extension_upload = strtolower(substr( strrchr($_FILES['avatar']['name'], '.') ,1));
if (!in_array($extension_upload,$extensions_valides) )
{
$i++;
$avatar_erreur3 = "Extension de l'avatar incorrecte";
}
}
?>
|
Certaines parties de ce code sont assez compliquées, mais elles sont détaillées dans le tutoriel de DHKold. Sachez simplement qu'on utilise le même système que précédemment, avec la variable
i qui s'incrémente à chaque erreur.
Quelques remarques toutefois.
- Les variables
$maxsize,
$maxwidth... définissent les limites de tailles, de poids et les extensions des avatars. Vous pouvez les modifier comme vous voulez : sachez bien que la partie 2 de ce tutoriel permettra de le faire directement à partir du panneau d'admin (il en va de même pour toutes les données chiffrées de cette page).
- L'intérêt d'ajouter la fonction
strtolower() (qui convertit une chaîne en minuscules) est que les extensions de vos fichiers images seront tous en minuscules. Ainsi, une extension .JPG sera quand même reconnue comme valide.
Et on ne vérifie pas la localisation ?

Bah, en fait, je ne vois pas trop ce qu'on peut vérifier dans ce champ. Aucune
regex ne peut vérifier le nom d'une ville, et on peut le laisser vide.
On affiche le message !
Voilà : maintenant qu'on a fait tous nos tests, il reste plus qu'à afficher le message.
Code : PHP 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56 | <?php
if ($i==0)
{
echo'<h1>Inscription terminée</h1>';
echo'<p>Bienvenue '.stripslashes(htmlspecialchars($_POST['pseudo'])).' vous êtes maintenant inscrit sur le forum</p>
<p>Cliquez <a href="./index.php">ici</a> pour revenir à la page d accueil</p>';
//La ligne suivante sera commentée plus bas
$nomavatar=(!empty($_FILES['avatar']['size']))?move_avatar($_FILES['avatar']):'';
$query=$db->prepare('INSERT INTO forum_membres (membre_pseudo, membre_mdp, membre_email,
membre_msn, membre_siteweb, membre_avatar,
membre_signature, membre_localisation, membre_inscrit,
membre_derniere_visite)
VALUES (:pseudo, :pass, :email, :msn, :website, :nomavatar, :signature, :localisation, :temps, :temps)');
$query->bindValue(':pseudo', $pseudo, PDO::PARAM_STR);
$query->bindValue(':pass', $pass, PDO::PARAM_INT);
$query->bindValue(':email', $email, PDO::PARAM_STR);
$query->bindValue(':msn', $msn, PDO::PARAM_STR);
$query->bindValue(':website', $website, PDO::PARAM_STR);
$query->bindValue(':nomavatar', $nomavatar, PDO::PARAM_STR);
$query->bindValue(':signature', $signature, PDO::PARAM_STR);
$query->bindValue(':localisation', $localisation, PDO::PARAM_STR);
$query->bindValue(':temps', $temps, PDO::PARAM_INT);
$query->execute();
//Et on définit les variables de sessions
$_SESSION['pseudo'] = $pseudo;
$_SESSION['id'] = $db->lastInsertId(); ;
$_SESSION['level'] = 2;
$query->CloseCursor();
}
else
{
echo'<h1>Inscription interrompue</h1>';
echo'<p>Une ou plusieurs erreurs se sont produites pendant l incription</p>';
echo'<p>'.$i.' erreur(s)</p>';
echo'<p>'.$pseudo_erreur1.'</p>';
echo'<p>'.$pseudo_erreur2.'</p>';
echo'<p>'.$mdp_erreur.'</p>';
echo'<p>'.$email_erreur1.'</p>';
echo'<p>'.$email_erreur2.'</p>';
echo'<p>'.$msn_erreur.'</p>';
echo'<p>'.$signature_erreur.'</p>';
echo'<p>'.$avatar_erreur.'</p>';
echo'<p>'.$avatar_erreur1.'</p>';
echo'<p>'.$avatar_erreur2.'</p>';
echo'<p>'.$avatar_erreur3.'</p>';
echo'<p>Cliquez <a href="./register.php">ici</a> pour recommencer</p>';
}
}
?>
</div>
</body>
</html>
|
Comment ça marche, ce code ? Notre variable
$i nous indique le nombre d'erreurs, c'est pourquoi on a juste à vérifier qu'elle soit égale à 0 pour savoir si tout colle.
Et si jamais ce n'est pas le cas, on affiche tous les messages d'erreurs qu'on a créés auparavant.
Une fois que le tout est bouclé, on peut dire qu'on a terminé le système de
login et d'inscription du forum. L'avantage par rapport à un forum comme phpbb, c'est que rien ne vous empêche de mettre les champs de connexions dans le menu plutôt que de mettre un lien (bon, c'était possible aussi avec phpbb, mais un peu plus compliqué ; puis là, vous savez comment marche votre système

).
Retour sur l'avatar
Revenons un peu sur cette ligne :
Code : PHP | <?php
$nomavatar=(!empty($_FILES['avatar']['size']))?move_avatar($_FILES['avatar']):'';
?>
|
On s'occupe ici de déplacer l'avatar qui a été uploadé. Malheureusement pour vous, la fonction
move_avatar n'est pas native de php, il va falloir la créer, pour cela, pas de panique, rendez-vous sur le fichier
function.php.
La fonction
move_avatar va prendre en argument la variable de type array
$avatar qui contiendra les infos sur le fichier à uploader (je vous renvoie sur le tuto de DHKold pour plus de précisions), elle va renvoyer un message si l'upload s'est bien passé et s'occupera d'enregistrer le fichier.
Code : PHP | <?php
function move_avatar($avatar)
{
$extension_upload = strtolower(substr( strrchr($avatar['name'], '.') ,1));
$name = time();
$nomavatar = str_replace(' ','',$name).".".$extension_upload;
$name = "./images/avatars/".str_replace(' ','',$name).".".$extension_upload;
move_uploaded_file($avatar['tmp_name'],$name);
return $nomavatar;
}
?>
|
Dans un premier temps, on lui donne le nom du
timestamp actuel afin que celui-ci soit unique. Ensuite, on s'occupe d'ajouter l'extension. Le tout, nom de l'image + extension, est envoyé dans la base de données. Enfin, la fonction
move_uploaded_file() déplace l'image dans le dossier
images/avatars.
Il faut donc que vous ayez créé un dossier avatars dans le dossier images. Pensez donc à mettre un CHMOD correct (à priori, sous windows, il est inutile de changer quoi que ce soit).