Mis à jour le vendredi 14 avril 2017
  • 10 heures
  • Facile

Ce cours est visible gratuitement en ligne.

Vous pouvez être accompagné et mentoré par un professeur particulier par visioconférence sur ce cours.

J'ai tout compris !

TP : le tchat en AJAX

Connectez-vous ou inscrivez-vous pour bénéficier de toutes les fonctionnalités de ce cours !

Mettons en pratique ce que vous venez d'apprendre tout au long de cette partie sur AJAX.

Nous allons ici créer un petit tchat en AJAX, qui permettra aux visiteurs de laisser un message qui sera rendu visible directement à tous les autres participants à la conversation.

Explications et pré-requis

Dans ce travail pratique, vous vous chargerez de créer un tchat en AJAX. Nous allons détailler ici la manière dont il faut procéder.

Le système de tchat

Les tchats en AJAX sont très répandus sur le web, on en trouve généralement sur les pages d'accueil des forums où les membres peuvent laisser un message qui sera instantanément transmis à tous les autres membres, pour peu qu'ils soient connectés au forum.

Un TP simple

Nous voulons un système similaire, bien que plus simple. À son arrivée sur la page, l'utilisateur verra deux zones qui lui seront proposées. Sur le haut de la page, il verra les messages du tchat qui seront postés. Sur la partie inférieure de la page, il trouvera un petit formulaire HTML, dans lequel il pourra renseigner son pseudo et son message. Un bouton lui permettra d'envoyer son message, et celui-ci sera ajouté au tchat sans rechargement de page.

Toutes les 5 secondes, une vérification sera faite : des nouveaux messages ont-ils été postés ? Si oui, ils seront affichés. Si non, on affichera un petit message d'information : « aucun message n'a été ajouté dans les 5 dernières secondes ».

Les technologies à utiliser

Pas de rechargement : AJAX !

Nous avons évoqué l'idée que l'utilisateur doit pouvoir poster son message sans recharger la page, il va donc nous falloir utiliser de l'AJAX, comme nous l'avons vu dans toute cette partie du cours. Il va falloir utiliser plusieurs scripts côté serveur : l'un enverra les messages dans une base de données, et l'autre surveillera la base de données à intervalle de 5 secondes, pour voir si de nouveaux messages ont été postés.

Commencez !

Pensez à tout ce que nous avons dit dans ce cours. Créez votre application comme si vous n'utilisiez pas AJAX, et quand elle fonctionne parfaitement, ajoutez-y la bête ! C'est certainement la meilleure manière de ne pas se perdre et de rester organisé. Toutes les possibilités du PHP vous sont ouvertes : AJAX ne doit jamais être vu comme une limite, juste comme un moyen d'améliorer vos applications !

Bonne chance !

Correction

Alors, c'était bien, vous avez pu vous torturer l'esprit mais enfin découvrir la solution à ce problème ? Comment ça, « non » ? Enfin qu'importe, maintenant que vous avez pu réfléchir, nous allons pouvoir vous proposer l'une des nombreuses solutions à ce problème.

Les fichiers nécessaires

Le fichier HTML

Notre problématique était de créer un tchat en AJAX, et vous saviez que l'utilisateur devait avoir un formulaire HTML pour lui permettre de renseigner pseudo et message. Pourquoi ne pas commencer par ici ? Étant donné que c'est la base de notre application, autant prendre ce formulaire comme point de départ. Également, nous avons besoin d'une zone où viendront se placer les messages du tchat.

<!DOCTYPE html>
<html>
    <head>
	<title>Le tchat en AJAX !</title>
    </head>
	
    <body>
        <div id="messages">
            <!-- les messages du tchat -->
        </div>

	<form method="POST" action="traitement.php">
	    Pseudo : <input type="text" name="pseudo" id="pseudo" /><br />
	    Message : <textarea name="message" id="message"></textarea><br />
	    <input type="submit" name="submit" value="Envoyez votre message !" id="envoi" />
	</form>
    </body>
</html>

C'est très basique, comme d'habitude, vous devriez être capable de comprendre tout cela.

Prochaine étape : le PHP et le SQL

Oui ! C'est un tuyau que nous allons vous donner. Lorsque vous souhaitez réaliser une application utilisant de l'AJAX, pensez toujours à la créer d'abord en PHP classique, puis ajoutez-y l'AJAX ! Vous tirerez deux avantages à cette pratique :

  • Une meilleure organisation.

  • L'assurance que votre application fonctionnera même si JavaScript est désactivé.

Nous allons donc devoir dès maintenant créer notre fichier PHP qui va se charger d'envoyer les informations tapées dans le formulaire en base de données. Ce fichier PHP va devoir exploiter une base de données. Nous allons donc devoir créer une base de données. Elle sera très simple, elle contiendra une seule table message contenant le pseudo de l'auteur et son message.

CREATE TABLE IF NOT EXISTS `messages` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `auteur` varchar(100) NOT NULL,
  `message` text NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

C'est tout bon, créez cette table (nous utilisons MySQL) dans une base de données quelconque et vous aurez le même schéma que nous.

Focalisons-nous sur le PHP

Nous allons maintenant devoir créer un fichier PHP qui envoie en base de données ce qui a été tapé dans le formulaire HTML. Nous utiliserons PDO, les fonctions mysql_* étant dépréciées.

<?php

// on se connecte à notre base de données
try
{
    $bdd = new PDO('mysql:host=localhost;dbname=tchat', 'root', '');
}
catch (Exception $e)
{
    die('Erreur : ' . $e->getMessage());
}

if(isset($_POST['submit'])){ // si on a envoyé des données avec le formulaire

    if(!empty($_POST['pseudo']) AND !empty($_POST['message'])){ // si les variables ne sont pas vides
    
        $pseudo = mysql_real_escape_string($_POST['pseudo']);
        $message = mysql_real_escape_string($_POST['message']); // on sécurise nos données

        // puis on entre les données en base de données :
        $insertion = $bdd->prepare('INSERT INTO messages VALUES("", :pseudo, :message)');
        $insertion->execute(array(
            'pseudo' => $pseudo,
            'message' => $message
        ));

    }
    else{
        echo "Vous avez oublié de remplir un des champs !";
    }

}

?>

Voilà un code basique en PHP. Rien ne vous empêche de faire plus de vérifications, évidemment, car on n'est jamais trop prudent. Passons maintenant à l'étape qui nous intéresse !

Rendons tout cela plus dynamique

La première chose à faire est d'inclure jQuery dans le fichier HTML.

Vous pourrez ensuite vous charger d'initialiser une requête AJAX, et récupérer les données qui vous intéressent dans le formulaire. Comme la requête sera de type POST, vous pouviez soit utiliser $.ajax(), soit $.post(). Pour un maximum de souplesse et de simplicité, nous allons utiliser la première méthode dans ce TP :

var pseudo = encodeURIComponent( $('#pseudo').val() ); // on sécurise les données
var message = encodeURIComponent( $('#message').val() );

if(pseudo != "" && message != ""){ // on vérifie que les variables ne sont pas vides
    $.ajax({
        url : "traitement.php", // on donne l'URL du fichier de traitement
        type : "POST", // la requête est de type POST
        data : "pseudo=" + pseudo + "&message=" + message // et on envoie nos données
    });
}

Le problème, c'est que ce code va s'exécuter dès le chargement de la page. Nous, on veut envoyer des données après le clic sur le bouton d'envoi ! Il suffit alors d'utiliser un évènement ici :

$('#envoi').click(function(e){
    e.preventDefault(); // on empêche le bouton d'envoyer le formulaire

    var pseudo = encodeURIComponent( $('#pseudo').val() ); // on sécurise les données
    var message = encodeURIComponent( $('#message').val() );

    if(pseudo != "" && message != ""){ // on vérifie que les variables ne sont pas vides
        $.ajax({
            url : "traitement.php", // on donne l'URL du fichier de traitement
            type : "POST", // la requête est de type POST
            data : "pseudo=" + pseudo + "&message=" + message // et on envoie nos données
        });
    }
});

Enfin, pour un maximum de dynamisme, nous allons ajouter le message directement dans la zone prévue à cet effet :

$('#envoi').click(function(e){
    e.preventDefault(); // on empêche le bouton d'envoyer le formulaire

    var pseudo = encodeURIComponent( $('#pseudo').val() ); // on sécurise les données
    var message = encodeURIComponent( $('#message').val() );

    if(pseudo != "" && message != ""){ // on vérifie que les variables ne sont pas vides
        $.ajax({
            url : "traitement.php", // on donne l'URL du fichier de traitement
            type : "POST", // la requête est de type POST
            data : "pseudo=" + pseudo + "&message=" + message // et on envoie nos données
        });

       $('#messages').append("<p>" + pseudo + " dit : " + message + "</p>"); // on ajoute le message dans la zone prévue
    }
});

L'envoi de messages est bouclé ! Il n'y a plus qu'à récupérer les messages postés en vérifiant toutes les cinq secondes dans la BDD s'il y en a de nouveaux.

Récupérer les messages

Il faut maintenant s'occuper de récupérer les messages en base de données. D'abord, nous allons récupérer les dix derniers postés, en PHP classique. Puis, à intervalle de 5 secondes, il s'agira de vérifier s'il y en a eu de nouveaux, et si c'est le cas, de les afficher.

Le fichier d'index revisité

C'est un code très classique en PHP :

<!DOCTYPE html>
<html>
    <head>
	<title>Le tchat en AJAX !</title>
    </head>
	
    <body>
        <div id="messages">
            <!-- les messages du tchat -->

            <?php

                // on se connecte à notre base de données
                try
                {
                    $bdd = new PDO('mysql:host=localhost;dbname=tchat', 'root', '');
                }
                catch (Exception $e)
                {
                    die('Erreur : ' . $e->getMessage());
                }

                // on récupère les 10 derniers messages postés
                $requete = $bdd->query('SELECT * FROM messages ORDER BY id DESC LIMIT 0,10');

                while($donnees = $requete->fetch()){
                    // on affiche le message (l'id servira plus tard)
                    echo "<p id=\"" . $donnees['id'] . "\">" . $donnees['pseudo'] . " dit : " . $donnees['message'] . "</p>";
                }

                $requete->closeCursor();

            ?>

        </div>

	<form method="POST" action="traitement.php">
	    Pseudo : <input type="text" name="pseudo" id="pseudo" /><br />
	    Message : <textarea name="message" id="message"></textarea><br />
	    <input type="submit" name="submit" value="Envoyez votre message !" id="envoi" />
	</form>

        <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
        <script src="main.js"></script>
    </body>
</html>

Le plus récent se trouvera en première position. Nous allons maintenant voir comment créer un code jQuery permettant de charger les nouveaux messages.

Charger les messages à intervalle de 5 secondes

Pour lancer une action toutes les 5 secondes, il suffisait d'utiliser setTimeout(), que nous avons déjà rencontré dans ce tutoriel. En créant une fonction se répétant indéfiniment, il suffisait d'indiquer un intervalle de 5000 millisecondes et le tour était joué. Le reste, c'était de l'AJAX classique avec du jQuery et du PHP.

function charger(){

    setTimeout( function(){
        // on lance une requête AJAX
        $.ajax({
            url : "charger.php",
            type : GET,
            success : function(html){
                $('#messages').prepend(html); // on veut ajouter les nouveaux messages au début du bloc #messages
            }
        });

        charger(); // on relance la fonction

    }, 5000); // on exécute le chargement toutes les 5 secondes

}

charger();

La base étant posée, il fallait penser à une petite chose : depuis quel message doit-on commencer à compter dans la base de données ? En effet, nous n'allons pas à chaque fois charger tous les messages, mais seulement les nouveaux. Il faut donc passer l'id du message le plus récemment affiché au fichier PHP, pour qu'il récupère tous les messages ayant un id plus élevé.

Et comment récupérer cet id ? Tout simplement en le prenant dans l'identifiant du premier paragraphe ! Souvenez-vous, nous l'avions affiché précédemment dans le fichier d'index.

function charger(){

    setTimeout( function(){

        var premierID = $('#messages p:first').attr('id'); // on récupère l'id le plus récent

        $.ajax({
            url : "charger.php?id=" + premierID, // on passe l'id le plus récent au fichier de chargement
            type : GET,
            success : function(html){
                $('#messages').prepend(html);
            }
        });

        charger();

    }, 5000);

}

charger();

Et voilà, il ne restait plus qu'à aller chercher les messages en base de données :

<?php

// ...
// on se connecte à notre base de données

if(!empty($_GET['id'])){ // on vérifie que l'id est bien présent et pas vide

    $id = (int) $_GET['id']; // on s'assure que c'est un nombre entier

    // on récupère les messages ayant un id plus grand que celui donné
    $requete = $bdd->prepare('SELECT * FROM messages WHERE id > :id ORDER BY id DESC');
    $requete->execute(array("id" => $id));

    $messages = null;

    // on inscrit tous les nouveaux messages dans une variable
    while($donnees = $requete->fetch()){
        $messages .= "<p id=\"" . $donnees['id'] . "\">" . $donnees['pseudo'] . " dit : " . $donnees['message'] . "</p>";
    }

    echo $messages; // enfin, on retourne les messages à notre script JS

}

?>

Terminé ! Bon, on reconnaît qu'il fallait penser à quelques subtilités, mais le résultat est là. Nous espérons que vous avez compris où sont vos erreurs si vous en avez fait, et que ce TP vous aura appris des choses. Quoi qu'il en soit, pratiquez ! :)

Améliorations

Nous sommes désolés de détruire votre rêve, mais ce tchat en AJAX ne va pas être directement réutilisable sur votre site. ^^

Idées d'amélioration

  • Ajouter des vérifications côté client. Cela vous permettra de revoir en même temps le TP sur le formulaire interactif !

  • Empêcher les utilisateurs d'utiliser les mêmes pseudos, vous utiliserez des sessions pour y arriver.

  • Un peu de BBcode, pourquoi pas ?

  • La possibilité d'entrer son email et/ou l'URL de son site dans le formulaire ?

  • Envoyer un email de notification aux utilisateurs du tchat chaque fois qu'un nouveau message y est posté.

  • Embellir un peu le tchat avec du CSS.

  • ...

Les possibilités sont infinies, c'est à vous de voir. Vous pouvez également décider de construire des systèmes totalement différents, tant que cela vous fait pratiquer, croyez-nous, c'est bon à prendre.

Vous venez de réaliser votre première mise en application concrète d'AJAX avec jQuery, nous n'avons désormais plus grand chose à vous apprendre sur AJAX, à vous de compléter votre formation permanente par toujours plus de pratique !

Exemple de certificat de réussite
Exemple de certificat de réussite