Créer un chat en PHP

Créer une messagerie instantanée en PHP / AJAX



Je vous propose de créer un tchat en PHP / AJAX très complet. Vous pouvez égelement 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>

                  <?php
                     if(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
      }
   }
?>
Par Clouder le 29 Oct 2017
Cette pub permet au site de vivre ...

8 commentaires

Tu veux participer ?
Alors connecte toi ou inscris toi et viens participer !
landers
le 29 Mar 2019 à 02:33


Clouder
le 16 Feb 2019 à 10:20
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 🙂
Theo
le 26 Dec 2018 à 01:44
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 ! 
Clouder
le 06 Mar 2018 à 14:53
De rien ! 🙂
malsain94
le 06 Mar 2018 à 10:55
Merci beaucoup je vais tester sa 🙂
Clouder
le 03 Mar 2018 à 13:17
Salut malsain94,

Oui aucun problème ! Je vais mettre le code dans l'article 🙂
malsain94
le 03 Mar 2018 à 02:06
super tuto !
code stp ? j'aimerais le personnalisé et evité si possible de tout refaire a la main déjà :s
merci d'avance
Fire and Ace
le 25 Feb 2018 à 22:30
Bonjour,

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

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