Projet Espace De Dialogue

Temps d'étude : 1h30 Niveau : Moyen.
Tags : Projet Espace De Dialogue
Fichier(s) utile(s) pour ce cours : /

Cas concret : Réalisation d'un espace de dialogue

Maintenant que nous avons pris des forces en PHP, nous allons pouvoir créer des pages web utiles et concretes.

Premier exemple concret, 1 espace de dialogue / commentaire (ex livre d'or et pouvant aussi être apparenté à 1 tchat).

Nous pouvons retrouver ce type de fonctionnalité sur FaceBook, YouTube et de nombreux autres sites permettant à leurs internautes de dialoguer en direct.

Quelles sont les différentes étapes afin de pouvoir créer cela ?

Tout d'abord, nous aurons besoin d'une base de données afin que les commentaires puissent être enregistrés dans une table.

Nous aurons également besoin d'une page web avec un formulaire afin de déposer des commentaires.


Etape 1 : Modélisation et création de la base de données, table et champs.

Base de données : dialogue
Table : commentaire

Champ Type Taille Spécificité
id_commentaire INT 3 Clé primaire (PK - Primary Key), AUTO_INCREMENT (AI)
pseudo VARCHAR 20 -
message TEXT - -
date_enregistrement DATETIME - -


Pour créer cette base de données, vous pouvez également passer par le gestionnaire de base de données PhpMyAdmin :
Accès à PhpMyAdmin :
explication PHP

Création d'une nouvelle base de données :
explication PHP

Création d'une nouvelle table :
explication PHP

Création de la structure de la table (champs/colonnes) :
explication PHP

Structure de la table (relecture) :
explication PHP



Pour créer cette base de données, vous pouvez également passer par la console Mysql :

explication PHP
explication PHP

Voici le code à insérer :

Base de données dialogue - Table commentaire
		CREATE DATABASE dialogue ;
		
		USE dialogue ;
		
		CREATE TABLE commentaire (
		id_commentaire INT( 3 ) NOT NULL AUTO_INCREMENT PRIMARY KEY ,
		pseudo VARCHAR( 20 ) NOT NULL ,
		message TEXT NOT NULL ,
		date_enregistrement DATETIME NOT NULL
		) ENGINE = InnoDB;	

Etape 2. Création d'un dossier et d'un fichier dialogue.php avec 1 ligne de code permettant la connexion à la base de données.

Une fois que la base de données a été créée, vous pouvez commencer à développer votre script.

/dialogue/
dialogue.php

dialogue.php
	<?php
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');	

Cette ligne de code nous permet de connecter notre page web (script) à la base de données.

Pour rappel, Msyqli est une classe permettant de se connecter à 1 base de données. Pour cela nous indiquons le nom du serveur, le pseudo, le mot de passe, le nom de la base de données.


Etape 3. Création d'un formulaire HTML (pour l'ajout de commentaire)

Nous allons créer un formulaire (au format HTML) afin que les internautes puissent s'exprimer (c'est bien le but de l'exemple !).

dialogue.php
	<?php
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	?>
	
	





Nous prévoyons 2 champs dans notre formulaire : pseudo & message.
Dans la table commmentaire de notre base de données dialogue, nous avions 4 champs : id_commentaire , pseudo , message , date_enregistrement.

Mais, nous n'allons pas demander à l'internaute de rentrer un id_commentaire, puisque notre système est prévu pour le faire automatiquement (clé primaire + auto increment) et ça ne se fait pas !

De la même manière, ce n'est pas à l'internaute de rentrer la date et l'heure de son propre message, nous tacherons d'utiliser une fonction prédéfinie permettant de le faire de manière automatisée.


Etape 4. Récupération et affichage des saisies en PHP (POST) sur la même page.

Maintenant que nous avons notre formulaire permettant la saisie de commentaires, il nous faut prévoir du code de récupération afin de "capter" les saisies de l'internaute.

dialogue.php
	<?php
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	if($_POST)
	{
		echo "pseudo posté: $_POST[pseudo] 
"; echo "message posté: $_POST[message]
"; } ?>





Nous ajoutons une condition IF pour dire que si l'internaute nous poste quelque chose (cette action est liée au clic sur le bouton submit), et bien nous affichons les saisies de l'internaute pour être certain de les "capter", avant de les enregistrer dans notre base de données.

L'affichage des saisies de l'internaute se fait grâce à la superglobale $_POST.


Etape 5. Requete SQL d'enregistrement (INSERT)

Maintenant que nous avons un système qui nous permet de recevoir des données sur la page web, il serait utile d'enregistrer ces informations dans notre base afin de les garder en mémoire.

dialogue.php
	<?php
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	if($_POST)
	{
		//echo "pseudo posté: $_POST[pseudo] 
"; //echo "message posté: $_POST[message]
"; $mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('$_POST[pseudo]', '$_POST[message]', NOW())") OR DIE ($mysqli->error); echo '
Votre message a bien été enregistré.
'; } ?>





Nous utilisons la méthode (fonction) query() de l'objet $mysqli afin de formuler une requête (de type INSERT, insertion) qui va nous permettre d'enregistrer les informations dans notre base de données.

Voici ce que ça donne au niveau de nos champs :
  • id_commentaire : nous ne rentrons pas d'informations pour ce champ, AUTO_INCREMENT
  • pseudo : nous envoyons le pseudo posté, $_POST, par l'internaute
  • message : nous envoyons le message posté, $_POST, par l'internaute
  • date_enregistrement : nous utilisons la fonction SQL prédéfinie, NOW(), afin d'obtenir la date et l'heure du serveur au moment de l'enregistrement
Faites le test !

Résultat
explication PHP


Pour être sûr que l'enregistrement a bien été pris en compte, vous pouvez retourner dans PhpMyAdmin ou dans la console SQL pour voir le contenu :

id_commentaire pseudo message date_enregistrement
1 Joker Mon premier message ! 2015-07-30 10:30:11

explication PHP



Etape 6. Améliorer l'étape 5 d'enregistrement avec la gestion des apostrophes et réaliser quelques contrôles de saisie.

Notre espace de dialogue est fonctionnel et il se présente bien puisqu'il enregistre des commentaires, cependant on peut nous envoyer tout et n'importe quoi, il serait donc utile de contrôler les saisies qui rentrent dans notre formulaire.

Exemple : L'internaute peut envoyer un pseudo et un message complétement vide. Cela s'enregistrerait aussi (faites le test !).
Pour y remédier nous pouvons ajouter des conditions (avec l'aide de la fonction prédéfinie empty, pour vérifier si cela est vide ou n'est pas vide).

Autre Problématique : Actuellement, nous ne pouvons pas déposer de message avec une apostrophe car cela ferait dysfonctionner la requête SQL.
Voici ce que cela donnait lors de la 1ère insertion :
	$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('joker', 'Mon premier message !', NOW())") OR DIE ($mysqli->error);

Imaginons maintenant que nous souhaitions déposer le message suivant : Aujourd'hui il fait beau.
Voici la requête SQL :
	$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('joker', 'Aujourd'hui il fait beau', NOW())") OR DIE ($mysqli->error);
Cela pose problème puisqu'il y aura une apostrophe de trop dans la requête ! Regardez bien. Le dysfonctionnement ne nous permettra pas d'insérer l'enregistrement !

Voici donc quelques améliorations dans les contrôles et traitements des données :

dialogue.php
	<?php
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	if($_POST)
	{
		$_POST['pseudo'] = addslashes($_POST['pseudo']);
		$_POST['message'] = addslashes($_POST['message']);
		if(!empty($_POST['pseudo']) && !empty($_POST['message']))
		{
			$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('$_POST[pseudo]', '$_POST[message]', NOW())") OR DIE ($mysqli->error);
			echo '
Votre message a bien été enregistré.
'; } else { echo '
Afin de déposer un commentaire, veuillez svp remplir tous les champs du formulaire.
'; } } ?>





Nous avons ajouté l'attribut pattern en html pour accepter seulement certains caractères pour le pseudo de l'internaute mais il s'agit du code exécuté côté client qui pourrait être retiré par l'internaute (puisqu'il a accès au code source) et aussi non compatible avec d'anciens navigateurs. Il est donc vivement recommandé de renforcer ces contrôles dans la partie exécutée côté serveur, c'est à dire dans le code PHP.

La condition appuyée par la fonction prédéfinie !empty() permet de vérifier, avant d'enregistrer, si les saisies ne sont pas vides.

La fonction prédéfinie addslashes() permet d'ajouter automatiquement des anti-slash "\" avant chaque apostrophe.

Nous pouvons maintenant déposer des messages avec des apostrophes, voici ce que cela donnerait avec le message suivant : Aujourd'hui il fait beau

	$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('joker', 'Aujourd\'hui il fait beau', NOW())") OR DIE ($mysqli->error);

Vous pouvez remarquer la présence de l'anti-slash "\" généré automatiquement par la fonction prédéfinie addslashes(), cela permait de ne pas faire dysfonctionner la requête SQL.

Plusieurs points de sécurité seraient également à améliorer. Il reste faillible à diverses attaques. Notre exemple est donc fonctionnel mais non sécurisé.


Etape 7. Affichage des commentaires

Notre exemple n'est pas totalement terminé, il nous faut absolument prévoir une partie affichage des commentaires, sinon les internautes auront du mal à se répondre les uns les autres

dialogue.php
	<?php
	// Partie connexion à la BDD
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	//---------------------------------------------------------------------------------------------
	// Partie enregistrement
	if($_POST)
	{
		$_POST['pseudo'] = addslashes($_POST['pseudo']);
		$_POST['message'] = addslashes($_POST['message']);
		if(!empty($_POST['pseudo']) && !empty($_POST['message']))
		{
			$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('$_POST[pseudo]', '$_POST[message]', NOW())") OR DIE ($mysqli->error);
			echo '
Votre message a bien été enregistré.
'; } else { echo '
Afin de déposer un commentaire, veuillez svp remplir tous les champs du formulaire.
'; } } //--------------------------------------------------------------------------------------------- // Partie affichage des commentaires $résultat = $mysqli->query("SELECT * FROM commentaire"); while($commentaire = $résultat->fetch_assoc()) { echo '
'; echo '
Par: ' . $commentaire['pseudo'] . ', ' . $commentaire['date_enregistrement'] . '
'; echo '
' . $commentaire['message'] . '
'; echo '
'; } //--------------------------------------------------------------------------------------------- // Partie formulaire d'envoi de commentaire ?>





Explications pour obtenir de l'affichage :

Nous utilisons la méthode (fonction) query() de l'objet $mysqli afin de formuler une requête (de type SELECT, selection) qui va nous permettre de récupérer et d'afficher sur la page web les informations contenues dans notre base de données.

Nous récupérons les enregistrements dans la variable $résultat.
$résultat représente les enregistrements, techniquement c'est un objet Mysqli_result (c'est ce que la méthode query() renvoie lors d'une requête de selection).

La méthode fetch_assoc() utilisé sur l'objet Mysqli_result (par l'intermédiaire de la variable $résultat) permet de traiter les enregistrements (cela génère un tableau ARRAY) afin de pouvoir les exploiter. Combiné à la boucle while, cela permet aussi d'avancer de ligne en ligne dans les enregistrements de la table.

La boucle while est présente pour répéter le traitement autant de fois que nécessaire (s'il y a 10 enregistrements à afficher, nous ferons 10 tours de boucle afin d'exécuter le code permettant de faire un affichage 10 fois).

$commentaire est, à chaque tour de boucle, un nouveau tableau ARRAY contenant les enregistrements.
Nous "piochons" à l'intérieur du tableau array $commentaire avec l'utilisation des crochets [].

Résultat
explication PHP


Etape 8. Améliorer l'affichage : Ordonner et mettre les derniers commentaires en tête de liste, afficher la date au format Français, Afficher le nombre total de commentaires.

Voici le code de la partie affichage avec quelques améliorations (ordre, date, et nombre de commentaires)
dialogue.php
	<?php
	// Partie connexion à la BDD
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	//---------------------------------------------------------------------------------------------
	// Partie enregistrement
	if($_POST)
	{
		$_POST['pseudo'] = addslashes($_POST['pseudo']);
		$_POST['message'] = addslashes($_POST['message']);
		if(!empty($_POST['pseudo']) && !empty($_POST['message']))
		{
			$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('$_POST[pseudo]', '$_POST[message]', NOW())") OR DIE ($mysqli->error);
			echo '
Votre message a bien été enregistré.
'; } else { echo '
Afin de déposer un commentaire, veuillez svp remplir tous les champs du formulaire.
'; } } //--------------------------------------------------------------------------------------------- // Partie affichage des commentaires $résultat = $mysqli->query("SELECT pseudo, message, DATE_FORMAT(date_enregistrement, '%d/%m/%Y') AS datefr, DATE_FORMAT(date_enregistrement, '%H:%i:%s') AS heurefr FROM commentaire ORDER BY date_enregistrement DESC"); echo '<h2>' . $résultat->num_rows . ' commentaire(s)</h2>'; while($commentaire = $résultat->fetch_assoc()) { echo '
'; echo '
Par: ' . $commentaire['pseudo'] . ', le ' . $commentaire['datefr'] . ' à ' . $commentaire['heurefr'] . '
'; echo '
' . $commentaire['message'] . '
'; echo '
'; } //--------------------------------------------------------------------------------------------- // Partie formulaire d'envoi de commentaire ?>





La requête SQL a été légérement modifiée :
- Nous utilisons DATE_FORMAT afin de pouvoir transformer l'affichage de la date au format Français.
- Nous utilisons ORDER BY date_enregistrement DESC afin de pouvoir ré-ordonner l'affichage des enregistrements.

$résultat->num_rows permet d'afficher le nombre de commentaires déposés sur notre page web.


Etape 9. Effectuer un retour visuel de meilleure qualité (css)

Nous pouvons ajouter les entêtes habituelles (doctype, html, head, body,...) afin d'assurer la liaison avec une feuille de style CSS.
Voici une autre version du code possible :

dialogue.php
	<?php
	// Partie connexion à la BDD et initialisation
	$mysqli = new Mysqli('localhost', 'root', '', 'dialogue');
	$contenu = '';
	//---------------------------------------------------------------------------------------------
	// Partie enregistrement
	if($_POST)
	{
		$_POST['pseudo'] = addslashes($_POST['pseudo']);
		$_POST['message'] = addslashes($_POST['message']);
		if(!empty($_POST['pseudo']) && !empty($_POST['message']))
		{
			$mysqli->query("INSERT INTO commentaire (pseudo, message, date_enregistrement) VALUES ('$_POST[pseudo]', '$_POST[message]', NOW())") OR DIE ($mysqli->error);
			$contenu .= '
Votre message a bien été enregistré.
'; } else { $contenu .= '
Afin de déposer un commentaire, veuillez svp remplir tous les champs du formulaire.
'; } } //--------------------------------------------------------------------------------------------- // Partie affichage des commentaires $résultat = $mysqli->query("SELECT pseudo, message, DATE_FORMAT(date_enregistrement, '%d/%m/%Y') AS datefr, DATE_FORMAT(date_enregistrement, '%H:%i:%s') AS heurefr FROM commentaire ORDER BY date_enregistrement DESC"); $contenu .= '<h2>' . $résultat->num_rows . ' commentaire(s)'; while($commentaire = $résultat->fetch_assoc()) { $contenu .= '
'; $contenu .= '
Par: ' . $commentaire['pseudo'] . ', le ' . $commentaire['datefr'] . ' à ' . $commentaire['heurefr'] . '
'; $contenu .= '
' . $commentaire['message'] . '
'; $contenu .= '
'; } //--------------------------------------------------------------------------------------------- // Partie formulaire d'envoi de commentaire ?> <!Doctype html> <html> <head> <link rel="stylesheet" href="style.css"> </head> <body>
<?php echo $contenu; ?>
<form method="post" action="">



</form> </body> </html>

Nous avons prévu une variable $contenu qui est déclarée vide mais que l'on va remplir à chaque fois que nous devrons réaliser un affichage.
Cela aura pour but de retenir l'affichage (puisqu'il s'agira d'une affectation de variable) afin qu'il n'y est pas d'affichage avant les balises principales (doctype, html, head, body).
L'avantage c'est que notre code sera bien valide w3c et que nous pourrons choisir l'emplacement précis de l'affichage.

A vous de créer votre fichier style.css et de mettre un peu de code à l'intérieur avec les classes existantes sur notre page web :
style.css
	.erreur{ background: red; padding: 5px; }
	.validation{ background: green; padding: 5px; }
	.message{
	background: #d9e8fd;  : 500px; padding: 15px; 	margin: 10px auto;	border: 2px solid #6eaafb; }
	.titre{ text-align: center;	: 500px;	}
	.contenu{ : 500px;	font-style: italic;	}
	.commentaire{}	

Etape 10. Mise en ligne et Amélirations possibles.

Mise en ligne :
A vous de faire la mise en ligne ! c'est un bon exercice pour voir si tout fonctionne bien.
Pour cela, il vous faut un hebergement type ovh, 1&1, planethoster, etc.

Améliorations possible :
Enormément d'améliorations sont possibles !
  • Nous pourrions par exemple ajouter une partie ajax (mélange php+js) afin de mettre à jour automatiquement les messages (sans rechargement de page) lorsque plusieurs internautes communiquent.

  • Nous pourrions aussi sécuriser notre page web.

  • Nous pourrions améliorer le graphisme avec l'aide du code html/css