Partage
  • Partager sur Facebook
  • Partager sur Twitter

Récupérer conversation de 2 membres

    13 février 2020 à 18:28:56

    Bonjour.

    J'ai fait un code pour récupérer une conversation entre 2 membre. je voudrai savoir si elle est optimisé et si elle marche.

    J'ai une table conversation avec 2 colonnes id|title et une table  connection_conversation avec 2 colonnes id_conversation|id_membre

    que vous compreniez bien :
    J'ai :
    id_conversation|id_membre
    1|1
    1|2
    2|1
    2|3
    Si je veux récupérer la conversation entre les membre 1 et 2 je récupéré la conversation n°1. Si je veux récupérer la conversation entre le membre 1 et 3 je récupéré la conversation n° 2. Si je veux récupérer la conversation entre 2 et 3 je veux créer la conversation car elle n'existe pas.

    Mon code et comme suit :

    <?php
    session_start();
    
    $db = new PDO('mysql:host=localhost;dbname=chat;charset=utf8', 'root', '');
    
    $req = $db->prepare("SELECT id_conversation FROM connection_conversation WHERE id_conversation = (SELECT id_conversation FROM connection_conversation WHERE id_membre = (:getinfo) INNER JOIN connection_conversation ON connection_conversation.id_membre = (:sessioninfo)) ORDER BY id_conversation");
    $req->execute(array(':getinfo' => $_GET['id'], ':sessioninfo' => $_SESSION['id']));
    $conversationInCommun = $req->fetchAll();
    $soloConversation;
    if (count($conversationInCommun)>1) {
    	for($i=2;i<count($conversationInCommun); $i++){
    		if($conversationInCommun[$i-2]['id_conversation']==$conversationInCommun[$i-1]['id_conversation'] && $conversationInCommun[$i-1]['id_conversation']!=$conversationInCommun[$i]){
    			$soloConversation = $conversationInCommun[$i-2]['id_conversation'] ;
    		}
    		break;
    	}
    }
    else{
    	$req3 = $db->prepare("INSERT INTO conversation VALUES (?)");
    	$req3->execute(array('null'));
    	$soloConversation = $db->lastInsertId();
    	$req4 = $db->prepare("INSERT INTO connection_conversation VALUES (?,?)");
    	$req4->execute(array($soloConversation, $_GET['id']));
    
    	$req5 = $db->prepare("INSERT INTO connection_conversation VALUES (?,?)");
    	$req5->execute(array($soloConversation,  $_SESSION['id']));
    }
    
    
        ob_start();?>
        <div class="chatWindows">
    	  <div id="column">
    	    <div id="monchat" data-id-conversation="<?= $soloConversation ?> ">
    	      <div id="reverse" onscroll="loadMore()"><div id="message"></div></div>
    	      <form action="traitement/traitement_add_message-chat.php" method="POST" name="chat" id="formChat" onsubmit="return send()">
    	        <textarea onkeypress="submitOnEnter(event)" name="message" id="mess" rows="3"></textarea>
    	      </form>
    	    </div>
    	  </div>
        </div>
        <?php
        $content=ob_get_clean();
    
        echo $content;

    Je récupère d'abord tout les id_conversation en commun entre le membre a qui appartient la session et le membre a qui appartient l'id _GET grace a la ligne (je suis pas sur de cette ligne) :

    $req = $db->prepare("SELECT id_conversation FROM connection_conversation WHERE id_conversation = (SELECT id_conversation FROM connection_conversation WHERE id_membre = (:getinfo) INNER JOIN connection_conversation ON connection_conversation.id_membre = (:sessioninfo)) ORDER BY id_conversation");
    $req->execute(array(':getinfo' => $_GET['id'], ':sessioninfo' => $_SESSION['id']));

    Ensuite je sélectionne l'id_conversation qui se suit 2 fois.

    Si elle n'existe pas je la crée.

    Est-ce bon ?

    Edit :

    C'est peut être mieux comme ca

    $req = $db->prepare("SELECT id_conversation FROM connection_conversation WHERE id_conversation=(SELECT id_conversation FROM connection_conversation WHERE id_membre = (:sessioninfo)) AND id_membre = (:getinfo) ORDER BY id_conversation");
    $req->execute(array(':getinfo' => $_GET['id'], ':sessioninfo' => $_SESSION['id']));

    -
    Edité par -Crixus- 13 février 2020 à 19:14:23

    • Partager sur Facebook
    • Partager sur Twitter

    "Etre vrai, peu le peuvent."
    Friedrich Nietzsche

      14 février 2020 à 9:50:56

      Bonjour,

      Une conversation ne concerne que 2 utilisateurs ou plus ? Dans les exemples donnés, c'est toujours 2 ...

      -
      Edité par Benzouye 14 février 2020 à 9:51:08

      • Partager sur Facebook
      • Partager sur Twitter
      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
        14 février 2020 à 19:43:47

        Bonjour.

        Oui c'est uniquement pour les discutions entre 2 utilisateurs.

        Pour récupérer les discutions a plus de 2 utilisateurs je fait une autre fonction de récupération des données.

        En fait je liste les amis dans une div. tu peux cliquer sur les amis et ca lance cette fonction (ci dessus). ce qui lance un chat 1v1.

        Dans une autre div, je liste les conversations a +de 2 utilisateurs. les conversations de groupe.

        Je ne veux pas lister directement les conversations. Je veux lister les amis, puis les conversation de groupe. un peux sur le principe de facebook. Ca me permet de lister les amis pour lequel il ni a pas de conversation déja creer ou les amis pour lesquel il ni a pas de conversation 1v1. Ou encore de lancer une conversation avec des gens qui ne sont pas dans la liste d'ami.

        Ma seconde fonction est la bonne. Le code marche. Je suis pas sur qu'il soit optimisé.

        Voici mon code final :

        <?php
        session_start();
        
        $db = new PDO('mysql:host=localhost;dbname=chat;charset=utf8', 'root', '');
        
        $req = $db->prepare("SELECT id_conversation FROM connection_conversation WHERE id_conversation = (SELECT id_conversation FROM connection_conversation WHERE id_conversation IN (SELECT id_conversation FROM connection_conversation WHERE id_membre = (:sessioninfo)) AND id_membre = (:getinfo)) ORDER BY id_conversation");
        $req->execute(array(':getinfo' => $_GET['id'], ':sessioninfo' => $_SESSION['id']));
        $conversationInCommun = $req->fetchAll();
        $soloConversation;
        $null= null;
        if (count($conversationInCommun)==2) {
        	$soloConversation = $conversationInCommun[1]['id_conversation'];
        }
        elseif (count($conversationInCommun)>2) {
        	for($i=2;$i<count($conversationInCommun); $i++){
        		if($conversationInCommun[$i-2]==$conversationInCommun[$i-1] && $conversationInCommun[$i-1]!=$conversationInCommun[$i]){
        			$soloConversation = $conversationInCommun[$i-2]['id_conversation'];
        		break;
        		}
        	}
        }
        else{
        	$req3 = $db->prepare("INSERT INTO conversation (title) VALUES (?)");
        	$req3->execute(array($null));
        	$soloConversation = $db->lastInsertId();
        	$req4 = $db->prepare("INSERT INTO connection_conversation VALUES (?,?)");
        	$req4->execute(array($soloConversation, $_GET['id']));
        	$req5 = $db->prepare("INSERT INTO connection_conversation VALUES (?,?)");
        	$req5->execute(array($soloConversation,  $_SESSION['id']));
        }
        
        
            ob_start();?>
            <div class="chatWindows" id="<?= $soloConversation ?>">
        	  <div id="column">
        	    <div id="monchat" >
        	      <div data-id-conversation="<?= $soloConversation ?>" id="reverse">
        	      	<div class="message"></div>
        	      </div>
        	      <form action="traitement/traitement_add_message-chat.php" method="POST" name="chat" class="formChat" onsubmit="return send(this)">
        	        <textarea data-id-conversation="<?= $soloConversation ?>" onkeypress="submitOnEnter(event)" name="message" class="mess1" rows="3" autofocus="autofocus"></textarea>
        	        <input name="id_conversation" type="hidden" value="<?= $soloConversation ?>">
        	      </form>
        	    </div>
        	  </div>
            </div>
            <?php
            $content=ob_get_clean();
        
            echo $content;



        -
        Edité par -Crixus- 14 février 2020 à 19:46:35

        • Partager sur Facebook
        • Partager sur Twitter

        "Etre vrai, peu le peuvent."
        Friedrich Nietzsche

          15 février 2020 à 11:24:28

          Déjà, pour retrouver les conversations entre deux membres données (2 ids), je ferai :

          SELECT id_conversation
          FROM
          	connection_conversation C1
          		INNER JOIN connection_conversation C2
          			ON C1.id_conversation = C2.id_conversation
          WHERE
          	C1.id_membre = 'id membre connecté'
          	AND C2.id_membre = 'id membre recherché'

          C'est quand même plus court non ?

          • Partager sur Facebook
          • Partager sur Twitter
          Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
            16 février 2020 à 20:47:08

            J'ai pas encore l'habitude :)

            En effet c'est beaucoup plus simple comme ca. C'est ce qu'on appel une jointure interne ?

            -
            Edité par -Crixus- 16 février 2020 à 20:49:10

            • Partager sur Facebook
            • Partager sur Twitter

            "Etre vrai, peu le peuvent."
            Friedrich Nietzsche

              17 février 2020 à 8:54:11

              C'est une jointure interne (INNER JOIN), mais c'est surtout une auto-jointure (d'une table sur elle-même, avec deux alias différents).

              • Partager sur Facebook
              • Partager sur Twitter
              Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                20 février 2020 à 5:24:19

                Ca va pas ton truc...

                Parce que ca me selectionne les id de conversation en commun.

                En gros si le SESSION a 4 conversations en commun avec le GET la 1,2,3,4 ; il va me selectionner 1/2/3/4.

                Mais je sais pas laquelle choisir entre toutes ces conversations car moi je veux la seul et unique conversation ou il y a 2 membre, le session et le get.

                Si il y a 4 membre dans la 1 ; 2 membre dans la 2 ; 6 membre dans la 3 et 12 membre dans la 4, je veux choisir la 2 car il y a mon session et mon get et qu'elle a une longueur 2.

                avec ma requête, je triais par id conversation et du coup j'avais

                ID CONVERSATION | MEMBRE

                1>idmembre
                1>idmembre
                1>idget
                1>idsession

                2>idget
                2>idsession

                3>idmembre
                3>idmembre
                3>idmembre
                3>idmembre
                3>idget
                3>idsession

                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idmembre
                4>idget
                4>idsession

                Avec un array je pouvais vérifier que
                if (n-1==n et n-2!=n) {
                enregistrer l'id de la conversation;
                break;
                }

                as tu une solution ?

                -
                Edité par -Crixus- 20 février 2020 à 6:01:17

                • Partager sur Facebook
                • Partager sur Twitter

                "Etre vrai, peu le peuvent."
                Friedrich Nietzsche

                  20 février 2020 à 9:07:26

                  MarcKa a écrit:

                  Parce que ca me selectionne les id de conversation en commun.

                  En gros si le SESSION a 4 conversations en commun avec le GET la 1,2,3,4 ; il va me selectionner 1/2/3/4.

                  Oui.

                  MarcKa a écrit:

                  Mais je sais pas laquelle choisir entre toutes ces conversations car moi je veux la seule et unique conversation ou il y a 2 membre, le session et le get.

                  Je n'avais pas compris cette exigences. Par contre selon ton modèle, entre deux membres, et seulement ces deux, il peut y avoir plusieurs conversations ... et d'ailleurs, ton code de départ ne traitait pas non plus ce cas là ...

                  Pour ne retourner que les conversations exclusivement entre ces deux membres, il faut compter le nombre de participants pour chaque conversation et exclure celles avec plus de deux ... Je ferai ceci :

                  SELECT C1.id_conversation
                  FROM
                  	connection_conversation C1
                  		INNER JOIN connection_conversation C2
                  			ON C1.id_conversation = C2.id_conversation
                  		INNER JOIN (
                  				-- Conversation avec exactement 2 participants
                  				SELECT id_conversation
                  				FROM connection_conversation
                  				GROUP BY id_conversation
                  				HAVING COUNT(*) = 2
                  			) C3
                  			ON C1.id_conversation = C3.id_conversation
                  WHERE
                  	C1.id_membre = 'id membre connecté'
                  	AND C2.id_membre = 'id membre recherché'

                  Tu peux aussi envisager une solution avec jointure externe :

                  SELECT C1.id_conversation
                  FROM
                  	connection_conversation C1
                  		INNER JOIN connection_conversation C2
                  			ON C1.id_conversation = C2.id_conversation
                  		LEFT JOIN connection_conversation C3
                  			ON C2.id_conversation = C3.id_conversation
                  			AND C3.id_membre <> 'id membre connecté'
                  			AND C3.id_membre <> 'id membre recherché'
                  WHERE
                  	C1.id_membre = 'id membre connecté'
                  	AND C2.id_membre = 'id membre recherché'
                  	AND C3.id_conversation IS NULL

                  Ce sera peut-être un poil plus lent, mais le résultat devrait être identique.

                  -
                  Edité par Benzouye 20 février 2020 à 11:47:25

                  • Partager sur Facebook
                  • Partager sur Twitter
                  Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                    20 février 2020 à 19:32:02

                    Hello !

                    Merci pour tout ce que tu me montre. c'est cool d'avoir appris a utiliser Group By et Having.

                    du coup ca ne marcherai pas ca :

                    $req = $db->prepare("SELECT id_conversation FROM connection_conversation WHERE id_conversation = (SELECT c1.id_conversation FROM connection_conversation AS c1 INNER JOIN connection_conversation AS c2 ON c1.id_conversation = c2.id_conversation WHERE c1.id_membre = (:sessioninfo) AND c2.id_membre = (:getinfo) ) GROUP BY id_conversation HAVING COUNT(*) = 2");


                    Sur mon test ca marche... j'ai qu'une conversation en commun entre mon get et mon session. Donc je suis pas sur que si yen a plusieurs ca marche. J'ai vu que pour utiliser plusieur or il fallait utiliser IN. Peut être que pour utiliser plusieur AND il y a un opérateur. Ou peut être pas au quel cas ma requète est fonctionnel.

                    J'ai peur que tas première requête soit trop longue si il y a des millier de conversation de longueur 2.

                    Tas seconde requête a l'air pas mal mais je la trouve pas très graphique. :)

                    Si la mienne marche c'est cool. Sinon peut être qu'il y a un opérateur comme IN pour OR, pour AND.

                    Sinon je prendrais tas seconde requête.

                    • Partager sur Facebook
                    • Partager sur Twitter

                    "Etre vrai, peu le peuvent."
                    Friedrich Nietzsche

                      20 février 2020 à 21:04:26

                      Je pense que des trois,  c'est ma première requête qui sera plus rapide, d'autant plus si tu crées une vue de la sous requête avec le COUNT.

                      Ta requête va planter si plusieurs conversations existent entre les 2 membres.

                      Et non, pas d'opérateur pour un AND "en série".

                      • Partager sur Facebook
                      • Partager sur Twitter
                      Seul on va plus vite, ensemble on va plus loin ... A maîtriser : Conception BDD, MySQL, PHP/MySQL
                        21 février 2020 à 0:36:30

                        Merci beaucoup pour toute ces réponses.
                        • Partager sur Facebook
                        • Partager sur Twitter

                        "Etre vrai, peu le peuvent."
                        Friedrich Nietzsche

                        Récupérer conversation de 2 membres

                        × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                        × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                        • Editeur
                        • Markdown