Créer un chat en PHP

Par Clouder le 29 Oct 2017 8 +99

Je vous propose de créer un tchat en PHP / AJAX très complet. Vous pouvez également regarder ma vidéo qui vous explique comment réaliser un tchat complet en PHP / AJAX.


Côté SQL


Table tchat


CREATE TABLE tchat (
  id int(255) NOT NULL,
  id_pseudo int(255) NOT NULL,
  message text COLLATE utf8mb4_unicode_ci NOT NULL,
  date_message datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


Table user


CREATE TABLE user (
  id int(255) NOT NULL,
  pseudo varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  sex int(1) NOT NULL,
  birthday date NOT NULL,
  mail varchar(255) COLLATE utf8mb4_unicode_ci NOT NULL,
  password text COLLATE utf8mb4_unicode_ci NOT NULL,
  register datetime NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;


Page tchat.php


Côté PHP

<?php
   session_start();

   include('bd/connexionDB.php');

   $see_tchat = $DB->query("SELECT t.*, u.pseudo 
      FROM tchat t
      LEFT JOIN user u ON u.id = t.id_pseudo
      ORDER BY date_message
      LIMIT 100");

   $see_tchat = $see_tchat->fetchAll();
?>


Côté HTML

<!DOCTYPE html>
<html lang="fr"><head><meta charset="utf-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1"><title>Accueil</title><link href=">css/jquery-ui.theme.min.css" rel="stylesheet" type="text/css"/><link href="css/jquery-ui.structure.min.css" rel="stylesheet" type="text/css"/><link href="css/jquery-ui.min.css" rel="stylesheet" type="text/css"/><link href="css/bootstrap.min.css" rel="stylesheet" type="text/css"><link href="css/style.css" rel="stylesheet" type="text/css"/><link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css">

   </head>

   <body><nav class="navbar navbar-default navbar-static-top"><div class="container"><div class="navbar-header"><button type="button" class="navbar-toggle collapsed" onclick="openNav(this)"> 
                  <span class="sr-only">Toggle navigation</span><span class="icon-bar bar1"></span><span class="icon-bar bar2"></span><span class="icon-bar bar3"></span></button><a class="navbar-brand" href="index.php">Accueil</a></div>

             <div id="myNav" class="overlay"><div class="overlay-content"><a href="condition.php">Conditions</a><a href="boucle.php">Boucles</a></div></div>

             <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"><ul class="nav navbar-nav navbar-right"><?php 
                     if(isset($_SESSION['id'])){
                  ?><li><a href="p_deconnexion.php">Se déconnecter</a></li><?php
                     }else{   
                  ?><li><a href="p_inscription.php">S'inscrire</a></li><li><a href="p_connexion.php">Se connecter</a></li><?php
                     }   
                  ?></ul></div></div></nav>

      <div class="container">      
         <div class="row"><div class="col-xs-12 col-sm-12 col-md-12"><div style="background: white; border-radius: 10px; box-shadow: 0 0 15px rgba(0, 0, 0, 0.1); padding: 10px">

                  <div style="font-size: 24px; font-weight: bold">Tchat</div>

                  <div id="msg" style="border: 1px solid #cccccc; padding: 10px 0; border-radius: 5px;overflow: scroll;height: 400px;margin: 10px 0; background: white"><?php   

                        foreach($see_tchat as $st){    

                           $date_message = date_create($st['date_message']);
                           $date_message = date_format($date_message, 'd M Y à H:i:s');

                           if(isset($_SESSION['id']) && $st['id_pseudo'] == $_SESSION['id']){
                        ?><div style="float: right;width: auto; max-width: 80%; margin-right: 26px;position: relative;padding: 7px 20px;color: #fff;background: #0B93F6;border-radius: 5px;margin-bottom: 15px; clear: both">

                              <span id="<?= $st['id'] ?>"><?= nl2br($st['message']) ?></span>

                              <div style="font-size: 10px; text-align: right; margin-top: 10px">Par <?= $st['pseudo'] ?>, le <?= $date_message ?></div></div><?php
                           }else{
                        ?><div style="position: relative;padding: 7px 20px;background: #E5E5EA;border-radius: 5px;color: #000;float: left;width: auto; max-width: 80%; margin-left: 10px;margin-bottom: 15px; clear: both">

                              <span id="<?= $st['id'] ?>"><?= nl2br($st['message']) ?></span>

                              <div style="font-size: 10px; text-align: right; margin-top: 10px">Par <?= $st['pseudo'] ?>, le <?= $date_message ?></div></div><?php
                           }
                        }   
                     ?><div id="message_recept"></div>                  
                  </div>

                  <?phpif(isset($_SESSION['id'])){   
                  ?><div style="border: 1px solid #cccccc; border-radius: 5px; position: relative; padding-top: 5px; background: white"><form method="post">

                              <textarea class="autoExpand" rows="1" data-min-rows="1" name="texte" id="message" class="msg" placeholder="Envoyer votre message" style="border: none;overflow: none; resize: none; width: 90%; outline: none; padding: 0 5px"></textarea>

                              <div style="position: absolute;top: -5px;right: 2px;font-size: 28px;"><input id="envoi" type="submit" class="fa fa-arrow-circle-up" value="" style="border: none; background: transparent; outline: none"/></div>      
                          </form>   
                       </div><?php
                      }       
                   ?></div></div></div></div>

      <footer><i class="fa fa-twitter social-cust"></i><i class="fa fa-facebook social-cust"></i><i class="fa fa-google-plus social-cust"></i></footer>

      <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script><script src="https://code.jquery.com/jquery-1.12.4.js"></script><script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script><script src="js/bootstrap.min.js"></script><script type="text/javascript">         
         var isopen = false;

         function openNav(x) {

            if(!isopen){
               isopen = !isopen;
               document.getElementById("myNav").style.height = "100%";
               x.classList.toggle("change");
            }else{
               isopen = !isopen;
               document.getElementById("myNav").style.height = "0%";
               x.classList.toggle("change");
            }

         }

         document.getElementById('msg').scrollTop = document.getElementById('msg').scrollHeight;      

         $('#envoi').click(function(e){
            e.preventDefault();

            var message = encodeURIComponent($('#message').val());

            message = message.trim();

            $('#message').val(null);

            if(message != ""){
                $.ajax({
                   url : 'function/send_mess.php?message=' + message,
                  type : 'GET',
                  dataType : "html",
                  success : function(data){
                       $("#message_recept").append(data);
                  }
                });
            }
         });

         setInterval("load_mess()", 1000);

           function load_mess(){  

              var lastID = $('#msg span:last').attr('id');

              if(lastID > 0){          
               $.ajax({
                  url : 'function/load_mess.php?id=' + lastID,
                  type : 'GET',
                  dataType : "html",
                  success : function(data){
                     $("#message_recept").append(data);
                  },
                  error : function(){
                     //alert("Oops une erreur est survenue lors du chargement du message !");
                  }
               });
            }
         };

         $(document).one('focus.autoExpand', 'textarea.autoExpand', function(){
             var savedValue = this.value;
             this.value = '';
             this.baseScrollHeight = this.scrollHeight;
             this.value = savedValue;

         }).on('input.autoExpand', 'textarea.autoExpand', function(){
             var minRows = this.getAttribute('data-min-rows')|0, rows;
             this.rows = minRows;
             rows = Math.ceil((this.scrollHeight - this.baseScrollHeight) / 20);
             this.rows = minRows + rows;
         });
      </script></body>
</html>


Page send_mess.php


<?php
   session_start();

   include ('../bd/connexionDB.php');

   $DB = new connexionDB();

   if(isset($_SESSION['id'])){ 

      $mess = htmlspecialchars(trim($_GET['message']));

      if(isset($mess) && !empty($mess)){

         $verif_user = $DB->query("SELECT id FROM user WHERE id = ?",
            array($_SESSION['id']));

         $verif_user = $verif_user->fetch();

         if(isset($verif_user['id'])){

            $date_message = date('Y-m-d H:i:s');

            $DB->insert("INSERT INTO tchat (id_pseudo, message, date_message) VALUES (?, ?, ?)",
               array($_SESSION['id'], $mess, $date_message));

            $lastID = $DB->query("SELECT id FROM tchat WHERE id_pseudo = ? ORDER BY date_message DESC LIMIT 1", 
               array($_SESSION['id']));

            $lastID = $lastID->fetch();

            $date_message = date_create($date_message);
            $date_message = date_format($date_message, 'd M Y à H:i:s');

            ?><div style="float: right;width: auto; max-width: 80%; margin-right: 26px;position: relative;padding: 7px 20px;color: #fff;background: #0B93F6;border-radius: 5px;margin-bottom: 15px; clear: both"><span id="<?= $lastID['id'] ?>"><?= nl2br($mess) ?></span>               
                  <div style="font-size: 10px; text-align: right; margin-top: 10px">Par <?= $_SESSION['pseudo'] ?>, le <?= $date_message ?></div></div>

               <script>document.getElementById('msg').scrollTop = document.getElementById('msg').scrollHeight;
               </script><?php

         }
      }      
   }
?>


Page load_mess.php


<?php
   session_start();

   include ('../bd/connexionDB.php');

   $DB = new connexionDB();

   if(isset($_GET['id'])){

      $id = (int) $_GET['id'];

      $see_tchat = $DB->query("SELECT t.*, u.pseudo 
         FROM tchat t
         LEFT JOIN user u ON u.id = t.id_pseudo
         WHERE t.id > ?
         ORDER BY date_message", 
         array($id));

      $see_tchat = $see_tchat->fetchAll();

      if (count($see_tchat) > 0){

         foreach($see_tchat as $st){

            $date_message = date_create($st['date_message']);
            $date_message = date_format($date_message, 'd M Y à H:i:s');

            if(isset($_SESSION['id']) && $st['id_pseudo'] == $_SESSION['id']){
               ?><div style="float: right;width: auto; max-width: 80%; margin-right: 26px;position: relative;padding: 7px 20px;color: #fff;background: #0B93F6;border-radius: 5px;margin-bottom: 15px; clear: both">

                     <span id="<?= $st['id'] ?>"><?= nl2br($st['message']) ?></span>

                     <div style="font-size: 10px; text-align: right; margin-top: 10px">Par <?= $st['pseudo'] ?>, le <?= $date_message ?></div></div><?php
            }else{
               ?><div style="position: relative;padding: 7px 20px;background: #E5E5EA;border-radius: 5px;color: #000;float: left;width: auto; max-width: 80%; margin-left: 10px;margin-bottom: 15px; clear: both">

                     <span id="<?= $st['id'] ?>"><?= nl2br($st['message']) ?></span>

                     <div style="font-size: 10px; text-align: right; margin-top: 10px">Par <?= $st['pseudo'] ?>, le <?= $date_message ?></div></div><?php
            }   
         }
         ?><script>document.getElementById('msg').scrollTop = document.getElementById('msg').scrollHeight;
         </script>   
      <?php
      }
   }
?>
Cette pub permet au site de vivre ...

8 commentaires

Tu veux participer ?
Alors connecte toi ou inscris toi et viens participer !

Salut Theo,

J'utilise une fonction query() afin d'aller plus vite pour écrire mes requêtes SQL. Pour que cela fonctionne soit tu changes mes requêtes SQL avec prepare et execute sinon va voir cet article la 🙂

Bonjour, je rencontre des erreurs lors du test du chat, notamment à la ligne 15 du fichier send_mess.php : PDO::query(): SQLSTATE[HY000]: Général error: mode must be a integer in ... (J’ai copié le code SQL de tes tables) merci de ton aide ! 

Merci beaucoup je vais tester ça 🙂

Salut malsain94,

Oui aucun problème !

Je vais mettre le code dans l'article 🙂

Super tuto !

Le code stp ?

J'aimerais le personnalisé et éviter si possible de tout refaire a la main déjà 😅


Merci d'avance

Bonjour,

Pourrais-je avoir le code sur l'article stp ? 🙂

Un grand merci d'avance et continu comme ça !!