Le principe du code reste inchangé et est détaillé dans ce message. Cependant les requêtes du script ci-dessous (qui date de 2008) utilisent l'extension mysql qui sera bientôt obsolète. Il est maintenant préférable d'utiliser mysqli ou PDO. Le code complet adapté pour PDO est disponible dans mon message suivant.
Préambule
Les scripts sont fonctionnels. Il suffit de créer la table ci-dessous, de faire un copier-coller du script et de modifier les lignes du code portant la mention "A modifier" par vos valeurs et ça roule

Cependant, si ce tuto est compréhensible pour les débutants, il pourra paraître obscur pour les "grands débutants". Si vous avez des difficultés pour comprendre, passez donc par la case départ en faisant les tutos de la colonne de droite de ce site http://www.phpdebutant.org/
Par ailleurs les fonctions utilisées sont cliquables, c'est à dire qu'en cliquant sur l'une d'entre elles vous aurez la définition du manuel php, une aide précieuse, sans oublier les exemples, commentaires, qui suivent leur définition.
Création de la table d'enregistrement :
Pour commencer, dans une fenêtre sql de phpMyAdmin, faire exécuter ce code pour créer la table "membres" qui servira pour enregistrer les nouveaux inscrits. C'est bien entendu un exemple de table minimaliste à compléter suivant vos besoins.
Code : Tout sélectionner
CREATE TABLE `membres` (
`ID` int(11) NOT NULL auto_increment,
`pseudo` varchar(100) NOT NULL,
`pass` varchar(100) character set utf8 collate utf8_bin NOT NULL,
`date_enregistrement` datetime NOT NULL,
PRIMARY KEY (`ID`),
UNIQUE KEY `pseudo` (`pseudo`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
- Le champ "pass" est formaté avec "collate utf8_bin" qui permet de faire la différence entre majuscules et minuscules (sensible à la casse) ce qui augmente le nombre de mots de passe possibles. Au contraire le champ pseudo sera insensible à la casse car un pseudo différencié d'un autre uniquement par une majuscule pourrait prêter à confusion.
- Le champ "date_enregistrement" est au format "datetime" qui permet - avec la fonction NOW() utilisée dans la requête d'insertion - d'enregistrer la date au format 'YYYY-MM-DD HH:MM:SS' .
Si vous êtes certain que les heures/minutes/secondes vous seront inutiles vous pourrez préférer le format "date" à la place de "datetime".
Ensuite vous trouverez le code PHP regroupé dans une seule page avec le formulaire HTML.
Concernant le formulaire de la partie HTML :
Code : Tout sélectionner
<form action = "#" method = "post">
<input type = "text" name = "pseudo" />
<input type = "password" name = "pass" />
<input type = "submit" value = "Envoyer" />
</form>
- "action" désigne l'adresse du fichier vers lequel seront envoyées les données du formulaire.
Dans cet exemple nous indiquons '#' pour indiquer la même page. - "method" désigne la méthode selon laquelle sont envoyées les données du formulaire.
Par défaut les données sont envoyées par la méthode "get" (dans l'url). Nous choisissons d'employer la méthode "post", plus sécurisée.
Les variables seront donc accessibles dans le tableau php "$_POST". - Dans les champs input, "type" porte bien son nom, et "name" indique l'index de l'élément du tableau qui sera créé dans le tableau "$_POST" de récupération des données. Ainsi la valeur du champ <input type = "text" name = "pseudo" /> sera enregistrée dans l'élément "$_POST['pseudo']" du tableau "$_POST".
Note : Pour plus de clarté, j'ai isolé dans l'extrait de code ci-dessus la partie du formulaire utile au traitement PHP.
Dans le script complet ci-dessous, les autres éléments du contenu html servent à titre d'exemple (qui pourrait-être amélioré) pour une mise en page conforme au standard html XHTML 1.1
1/ INSCRIPTION
Le code PHP est commenté au fil de l'eau et suit la logique :
- Récupération et vérification des données du visiteur envoyées dans le formulaire
- Connexion à la base de donnée
- Traitement des données avec la fonction mysql_real_escape_string() pour protéger les requêtes
- Requête dans la table "membres" pour vérifier si le pseudo est déjà utilisé ou non
- Si non : inscription des données du visiteur dans la table "membres"
- Si oui : affiche d'un message invitant à choisir un autre pseudo
Remarques :
- Pour le traitement des caractères, nous prenons le parti le travailler avec la norme UTF-8 qui permet d'afficher tous les caractères internationaux.
- J'utilise parfois la syntaxe $a = $condition ? $b : $c; équivalente à la syntaxe classique if($condition) {$a = $b;} else {$a = $c;}. Cette syntaxe qui utilise les opérateurs ternaires "?" et ":" est plus lisible et plus rapide à écrire pour les structures conditionnelles simples.
- La mention " or die(mysql_error())" qui suit certaines requêtes est très utile pour afficher les messages d'erreur en phase de test. Il est préférable de supprimer cette mention en phase d'utilisation : en cas de bug, les éventuels pirates auront d'autant moins d'informations.
Et maintenant, le script complet

Code : Tout sélectionner
<?php
/* Indique le bon format des entêtes (par défaut apache risque de les envoyer au standard ISO-8859-1) */
header('Content-type: text/html; charset=UTF-8');
/* Création d'une fonction - utilisée dans la récupération des variables - qui teste la configuration get_magic_quotes_gpc du serveur.
Si oui, supprime avec la fonction stripslashes les antislashes "\" insérés dans les chaines de caractère des variables gpc (GET, POST, COOKIE) */
function Verif_magicquotes ($chaine)
{
if (get_magic_quotes_gpc()) $chaine = stripslashes($chaine);
return $chaine;
}
/* Initialisation du message de réponse */
$message = null;
/* Si le formulaire est envoyé */
if (isset($_POST['pseudo']))
{
/* Récupération des variables issues du formulaire
Teste l'existence les données post en vérifiant qu'elles existent, qu'elles sont non vides et non composées uniquement d'espaces.
(Ce dernier point est facultatif et l'on pourrait se passer d'utiliser la fonction trim())
En cas de succès, on applique notre fonction Verif_magicquotes pour (éventuellement) nettoyer la variable */
$pseudo = (isset($_POST['pseudo']) && trim($_POST['pseudo']) != '')? Verif_magicquotes($_POST['pseudo']) : null;
$pass = (isset($_POST['pass']) && trim($_POST['pass']) != '')? Verif_magicquotes($_POST['pass']) : null;
/* Si $pseudo et $pass différents de null */
if(isset($pseudo,$pass))
{
/* Connexion au serveur : dans cet exemple, en local sur le serveur d'évaluation
A MODIFIER avec vos valeurs */
$hostname = "localhost";
$database = "nom_de_votre_base";
$username = "root";
$password = "";
$connection = mysql_connect($hostname, $username, $password) or die(mysql_error());
/* Connexion à la base */
mysql_select_db($database, $connection);
/* Indique à mySql de travailler en UTF-8 (par défaut mySql risque de travailler au standard ISO-8859-1) */
mysql_query("SET NAMES 'utf8'");
/* Préparation des données pour les requêtes à l'aide de la fonction mysql_real_escape_string */
$nom = mysql_real_escape_string($pseudo);
$password = mysql_real_escape_string($pass);
/* Requête pour compter le nombre d'enregistrements répondant à la clause : champ du pseudo de la table = pseudo posté dans le formulaire */
$requete = "SELECT count(*) as nb FROM membres WHERE pseudo = '".$nom."'";
/* Exécution de la requête */
$req_exec = mysql_query($requete) or die(mysql_error());
/* Création du tableau associatif du résultat */
$resultat = mysql_fetch_assoc($req_exec);
/* nb est le nom de l'allias associé à count(*) et retourne le résultat de la requête dans le tableau */ $resultat;
if (isset($resultat['nb']) && $resultat['nb'] == 0)
/* Résultat du comptage = 0 pour ce pseudo, on peut donc l'enregistrer */
{
/* Pour enregistrer la date actuelle (date/heure/minutes/secondes) on peut utiliser directement la fonction mysql : NOW() */
$insertion = "INSERT INTO membres(pseudo,pass,date_enregistrement) VALUES('".$nom."', '".$password."', NOW())";
/* Exécution de la requête d'insertion */
$inser_exec = mysql_query($insertion) or die(mysql_error());
/* Si l'insertion s'est faite correctement (une requête d'insertion retourne "true" en cas de succès, je peux donc utiliser
l'opérateur de comparaison strict '===' c.f. http://fr.php.net/manual/fr/language.operators.comparison.php) */
if ($inser_exec === true)
{
/* Démarre la session et enregistre le pseudo dans la variable de session $_SESSION['login']
qui donne au visiteur la possibilité de se connecter. */
session_start();
$_SESSION['login'] = $pseudo;
/* A MODIFIER Remplacer le '#' par l'adresse de votre page de destination, sinon ce lien indique la page actuelle. */
$message = 'Votre inscription est enregistrée. <a href = "#">Cliquez ici pour vous connecter</a>';
}
}
else
{ /* Le pseudo est déjà utilisé */
$message = 'Ce pseudo est déjà utilisé, changez-le.';
}
}
else
{ /* Au moins un des deux champs "pseudo" ou "mot de passe" n'a pas été rempli */
$message = 'Les champs "Pseudo" et "Mot de passe" doivent être remplis.';
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Formulaire d'inscription - tutoriel PHP France</title>
<style type="text/css">
<!--
body, p, h1,form, input {
margin:0;
padding:0;
}
body {
background-color:#FFFFFF
}
#inscription {
width:380px;
background:#FFFFFF;
margin:20px auto;
font-family: Arial, Helvetica, sans-serif;
font-size:1em;
border:2px solid #333333;
}
#inscription h1 {
text-align:center;
font-size:1.2em;
background:#333333;
padding-bottom:5px;
margin-bottom:15px;
color:#FFFFFF;
letter-spacing:0.05em;
}
#inscription p {
padding-top:15px;
padding-right:50px;
text-align:right;
}
#inscription input {
margin-left:30px;
width:150px;
}
#inscription #valider {
width:155px;
font-size:0.8em;
}
#inscription #message {
height:27px;
font-size:0.7em;
font-weight:bold;
text-align:center;
padding:10px 0 0 0;
}
-->
</style>
</head>
<body>
<div id = "inscription">
<form action = "#" method = "post">
<h1>Inscription</h1>
<p><label for = "pseudo">Pseudo : </label><input type = "text" name = "pseudo" id = "pseudo" /></p>
<p><label for = "pass">Mot de passe : </label><input type = "password" name = "pass" id = "pass" /></p>
<p><input type = "submit" value = "Envoyer" id = "valider" /></p>
</form>
<p id = "message"><?php if(isset($message)) echo $message ?></p>
</div>
</body>
</html>
Dans cet exemple, si l'enregistrement est effectué correctement on enregistre le pseudo dans la variable de session $_SESSION['login'].
- Les pages à protéger devront donc commencer par :
session_start(); if(!isset($_SESSION['login'])) {die('Vous devez être enregistré pour accéder à cette partie du site');}
- Vous pourrez donc afficher le pseudo du visiteur dans les pages où une session est démarrée en faisant:
echo htmlspecialchars($_SESSION['login']);
- On préfère souvent rediriger automatiquement le visiteur en remplaçant cette ligne par :
header("Location: nom_du_fichier_de_destination.php"); exit();
Voilà pour le script de base. Complétez-le à votre guise en ajoutant par exemple une fonction pour contrôler la longueur* minimum que vous autorisez pour le mot de passe, ajouter des champs pour un formulaire plus complet (enregistrement de l'e-mail etc...). A vous de jouer

* note : Etant donné que nous travaillons en UTF-8, la fonction usuelle strlen() serait inadaptée pour calculer la taille d'une chaîne de caractères car elle renverrait des valeurs erronées pour les caractères accentués (renvoie 2 pour un seul caractère accentué codé en UTF-8). On utilisera donc mb_strlen() en renseignant le paramètre optionnel $encoding de cette fonction. Dans notre exemple : $nb_caract_pass = mb_strlen($pass,"UTF-8");
Pour plus d'informations sur l'encodage UTF-8 : Tuto
Remarquez qu'il y a peu de choses à modifier pour transformer ce script d'inscription en script de connexion

2/ CONNEXION
Le code PHP est commenté au fil de l'eau et suit la logique :
- Récupération et vérification des données du visiteur envoyées dans le formulaire
- Connexion à la base de donnée
- Traitement des données avec la fonction mysql_real_escape_string() pour protéger les requêtes
- Requête dans la table "membres" pour vérifier si le pseudo et le mot de passe existent et correspondent
- Si oui : déclaration d'une variable de session pour autoriser la visite des pages à accès restreint et envoi d'un message et d'un lien pour redirection
- Si non : envoi d'un message d'information
Code : Tout sélectionner
<?php
/* Indique le bon format des entêtes (par défaut apache risque de les envoyer au standard ISO-8859-1) */
header('Content-type: text/html; charset=UTF-8');
/* Création d'une fonction - utilisée dans la récupération des variables - qui teste la configuration get_magic_quotes_gpc du serveur.
Si oui, supprime avec la fonction stripslashes les antislashes "\" insérés dans les chaines de caractère des variables gpc (GET, POST, COOKIE) */
function Verif_magicquotes ($chaine)
{
if (get_magic_quotes_gpc()) $chaine = stripslashes($chaine);
return $chaine;
}
/* Initialisation du message de réponse */
$message = null;
/* Si le formulaire est envoyé */
if (isset($_POST['pseudo']))
{
/* Récupération des variables issues du formulaire
Teste l'existence les données post en vérifiant qu'elles existent, qu'elles sont non vides et non composées uniquement d'espaces.
(Ce dernier point est facultatif et l'on pourrait se passer d'utiliser la fonction trim())
En cas de succès, on applique notre fonction Verif_magicquotes pour (éventuellement) nettoyer la variable */
$pseudo = (isset($_POST['pseudo']) && trim($_POST['pseudo']) != '')? Verif_magicquotes($_POST['pseudo']) : null;
$pass = (isset($_POST['pass']) && trim($_POST['pass']) != '')? Verif_magicquotes($_POST['pass']) : null;
/* Si $pseudo et $pass différents de null */
if(isset($pseudo,$pass))
{
/* Connexion au serveur : dans cet exemple, en local sur le serveur d'évaluation
A MODIFIER avec vos valeurs */
$hostname = "localhost";
$database = "nom_de_votre_base";
$username = "root";
$password = "";
$connection = mysql_connect($hostname, $username, $password) or die(mysql_error());
/* Connexion à la base */
mysql_select_db($database, $connection);
/* Indique à mySql de travailler en UTF-8 (par défaut mySql risque de travailler au standard ISO-8859-1) */
mysql_query("SET NAMES 'utf8'");
/* Préparation des données pour les requêtes à l'aide de la fonction mysql_real_escape_string */
$nom = mysql_real_escape_string($pseudo);
$password = mysql_real_escape_string($pass);
/* Requête pour récupérer les enregistrements répondant à la clause :
champ du pseudo et champ du mdp de la table = pseudo et mdp postés dans le formulaire*/
$requete = "SELECT * FROM membres WHERE pseudo = '".$nom."' AND pass = '".$password."'";
/* Exécution de la requête */
$req_exec = mysql_query($requete) or die(mysql_error());
/* Création du tableau associatif du résultat */
$resultat = mysql_fetch_assoc($req_exec);
/* Les valeurs (si elles existent) sont retournées dans le tableau $resultat; */
if (isset($resultat['pseudo'],$resultat['pass']))
{
/* Démarre la session et enregistre le pseudo dans la variable de session $_SESSION['login']
qui donne au visiteur la possibilité de visiter les pages protégées. */
session_start();
$_SESSION['login'] = $pseudo;
/* A MODIFIER Remplacer le '#' par l'adresse de votre page de destination, sinon ce lien indique la page actuelle. */
$message = 'Bonjour '.htmlspecialchars($_SESSION['login']).' <a href = "#">Cliquez ici pour vous connecter</a>';
}
else
{ /* Le pseudo ou le mot de passe sont incorrect */
$message = 'Le pseudo ou le mot de passe sont incorrect';
}
}
else
{ /* au moins un des deux champs "pseudo" ou "mot de passe" n'a pas été rempli */
$message = 'Les champs Pseudo et Mot de passe doivent être remplis.';
}
}
?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr"><head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Formulaire de connexion</title>
<style type="text/css">
<!--
body, p, h1,form, input {
margin:0;
padding:0;
}
body {
background-color:#FFFFFF
}
#connexion {
width:380px;
background:#FFFFFF;
margin:20px auto;
font-family: Arial, Helvetica, sans-serif;
font-size:1em;
border:2px solid #333333;
}
#connexion h1 {
text-align:center;
font-size:1.2em;
background:#333333;
padding-bottom:5px;
margin-bottom:15px;
color:#FFFFFF;
letter-spacing:0.05em;
}
#connexion p {
padding-top:15px;
padding-right:50px;
text-align:right;
}
#connexion input {
margin-left:30px;
width:150px;
}
#connexion #valider {
width:155px;
font-size:0.8em;
}
#connexion #message {
height:27px;
font-size:0.7em;
font-weight:bold;
text-align:center;
padding:10px 0 0 0;
}
-->
</style>
</head>
<body>
<div id = "connexion">
<form action = "#" method="post">
<h1>Connexion</h1>
<p><label for = "pseudo">Pseudo : </label><input type="text" name="pseudo" id="pseudo" /></p>
<p><label for = "pass">Mot de passe : </label><input type="password" name="pass" id="pass" /></p>
<p><input type="submit" value="Envoyer" id = "valider" /></p>
</form>
<p id = "message"><?php if(isset($message)) echo $message ?></p>
</div>
</body>
</html>

Note : Les mots de passe sont inscrits "en clair" dans la base de donnée. Habituellement on choisi de les "hasher" pour les rendre indéchiffrables. Si l'on choisi d'utiliser l'algorithm de hashage sha1 (plus performant que le md5), il suffit de remplacer dans les deux scripts ci-dessus, la ligne
$password = mysql_real_escape_string($pass);
par
$password = mysql_real_escape_string(sha1($pass));
