Bonjour a tous,

Je suis en train de développer un petit réseau social, et aujourd'hui, j'aimerais mettre au point un "système d'amis" entre les membres.
Je m'explique :

J'ai déja essayé une solution qui fonctionne, mais pas a 100%. La solution est d'envoyer une demande d'ajout, celle-ci est stockée en SQL dans ma table amis , a une autre personne, dite destinataire. Une fois que la personne destinataire se connecte, elle a la possibilité d'accepter ou de décliner l'invitation. Jusque la, tout va bien.

Ma table amis est comme ça :

id_invitation
pseudo_exp
pseudo_dest
date_invitation
date_confirmation
active (0 s'ils ne sont pas ami, 1 s'ils le sont)

Admettons maintenant, que la personne destinataire (pseudo_dest) accepte l'invitation.
Il va falloir afficher le profil du membre (pseudo_exp) qu'elle vient d'ajouter. Pas de soucis la dessus non plus.
Mon problème est le suivant, e souhaite maintenant afficher la liste des amis de l'utilisateur connecté.
Et la, aille aille aille....... Je ne vois pas comment m'y prendre.
C'est pour cela que je poste ce sujet sur le Forum Grafikart.

Pouvez vous m'aider dans la formulation de la requête SQL et dans le script PHP éventuellement svp ?
Dites moi si vous avez besoin de plus de renseignements.

Merci d'avance pour vos réponses.
Bonne journée
EnObliO.

36 réponses


fabsgc
Réponse acceptée

Salut,

m1 et m2 ce sont des alias parce qu'on utilise 2 fois la tables membre : la première fois pour récupérer les infors sur le membre connectés et la deuxième fois pour récupérer les infos sur les amis. Ca permet d'éviter les conflits vu que les noms des champs sont les mêmes

Salut,

je souhaite maintenant afficher la liste des membres de l'utilisateur connecté.

Est-ce que tu t'es trompé dans cette phrase ? Je n'arrive pas à comprendre ton problème.

EnObliO
Auteur

Bonjour SLK, oui effectivemment, je ne me suis pas relu, je souhaite maintenat afficher la liste des amis de l'utilisateurs connecté :)

Salut,

Tu as une table pivot pour stocker les ID des "amis" d'un user ?

Ah oui,

alors attend avant de parler requête SQL ou script PHP, il faut qu'on parle un peu de la table amis.
Telle qu'elle est actuellement,
chaque ligne "stock" des invitation, et il y a un champ active.
OK, on pourrait se dire qu'on peut "trouver" les amis de "Marc" en récupérant toutes les lignes où :
RÉSULTATS = ("pseudo_exp" == Marc OU "pseudo_dest" == Marc) ET active == 1
Maintenant on pourrait créer un tableau vide AMIS,
on boucle sur RÉSULTATS, et sur chaque itérations, on va dire que "l'ami" de Marc, est dans le champ où n'est PAS Marc (entre les 2 champs pseudo_dest et pseudo_exp). Oui parce-que "Marc" pourrait bien être dans l'un ou l'autre. Et on ajoute cet ami dans notre tableau AMIS.
À la fin de cette boucle on a récupéré tous les amis de Marc. (ouf)

Est-ce que cette façon de faire te convient ?
Ça m'a l'air un peu tiré par les cheveux, MAIS, j'ai du mal à trouver mieux...

Si on voudrait faire autrement, il faudrait repenser la structure de la base de données. Et je ne vois pas trop comment...

  • Soit on créer PLEIN de tables : marc_amis, jean_amis, marion_amis... (ça me parait mauvais comme façon de faire).
  • Soit on rajoute un champ "amis" dans la table "utilisateurs", et dans ce champ, on stock un "array" "serialisé" des amis de l'utilisateur.
  • Soit on reste sur notre 1ère façon de faire.
  • Peut-être qu'il y a une autre idée à laquelle je n'ai pas pensé.
EnObliO
Auteur

Bonjour, merci de vos réponses rapides !!!

betaWeb, tu entends quoi par une table pivot pour stocker les ID des "amis" d'un user ? Car je crois que c'est ce qu'il me faut.

En ce qui concerne ton idée SLK, je la trouve plutôt bien, mais juste une chose que je n'arrive pas trop à assimiler c'est cette histoire de pseudo_dest et pseudo_exp....
A vrai dire j'avais fais cette table car je trouvait que ces champs suffisaient pour faire fonctionner les relations, mais je me rend compte que c'est plus complexe que je le croyait.

J'arrive pour le moment a envoyer des requêtes d'amis, les anuler, accepter les requetes avec un autre utilisateur ou les refuser.
En ce qui concerne l'affichage, c'est pas ça ^^ mais en bidouillant 2 3 choses ça peux se faire.

Ce que je souhaiterais est de pouvoir afficher la liste des amis de Marc, la liste des amis de Marion, la liste des amis de X et tout ça, sans forcément avoir a être connecté sur le site.
Si un membre se connecte, je veux qu'il puisse voir ses amis a lui, et éventuellement, voir les amis qu'il a en commun avec un autre membre.

Cordialement,
EnObliO

juste une chose que je n'arrive pas trop à assimiler c'est cette histoire de pseudo_dest et pseudo_exp

Tu veux parler de ce passage ?
on va dire que "l'ami" de Marc, est dans le champ où n'est PAS Marc (entre les 2 champs pseudo_dest et pseudo_exp)
Je voulais dire que dans ta table amis, un enregistrement pourrait autant être :

id_invitation  =  4
pseudo_exp  =  Marc
pseudo_dest  =  Jean
...

que :

id_invitation  =  4
pseudo_exp  =  Jean
pseudo_dest  =  Marc
...

Comme on a récupéré toutes les lignes où il y a "Marc" quelque part (pseudo_exp OU pseudo_dest),
si on veut l'ami de Marc, il faut regarder dans l'autre "quelque part" (pseudo_exp OU pseudo_dest), c'est à dire le champ qui ne contient pas Marc (où Marc n'est pas).

Ce que je souhaiterais est de pouvoir afficher la liste des amis de Marc, la liste des amis de Marion, la liste des amis de X et tout ça, sans forcément avoir a être connecté sur le site.

Oui c'est bon, avec notre idée, pas besoin d'être connecté, pas de soucis.

Si un membre se connecte, je veux qu'il puisse voir ses amis a lui,

Oui OK, c'est bon avec ce qu'on fait.

et éventuellement, voir les amis qu'il a en commun avec un autre membre.

Pour les amis en commun, l'idée est simple.
Comme on sait récupérer les amis de "Marc", on sait aussi récupérer les amis de "Jean",
on a donc 2 tableaux "d'amis".
Les amis en commun (de Marc et de Jean) seront les noms qui seront présent dans les 2 tableaux.

amis_communs est un tableau vide
On boucle sur le tableau des amis de Marc, et à chaque itération,
SI inArray(ami_de_marc, tableau_amis_de_jean),
ALORS on ajoute ami_de_marc dans le tableau amis_commun
EnObliO
Auteur

Oui je comprends mieux maintenant, merci pour cette expliquation très claire !
Maintenant que le plan est posé, il nous reste a traduire tout ça en PHP ^^

Que me conseilles tu pour réaliser le système d'ami ?

Que me conseilles tu pour réaliser le système d'ami ?

Ouhlà j'en sais rien, moi j'aurai fais comme Facebook tout simplement... (tout simplement mais en plus simple quand même...).
Tu affiches ta liste d'amis, chaque ami de cette liste est un lien, qui renvoi vers la page de l'ami en question, avec ses détails (prénom, âge, photo...).
Et sur cette page de cet ami, en plus de ses détails, tu mets SA liste d'amis ET la liste de vos amis commun.

Maintenant que le plan est posé, il nous reste a traduire tout ça en PHP ^^

Moi je te donne des pistes, mais c'est toi qui code hein :)

On a bien éclaircit la chose là quand même, ça devrait te permettre de commencer.
Et tu peux toujours revenir ici si tu as un soucis que tu n'arrives pas à résoudre tout seul.
Mais vas y, lance-toi.

EnObliO
Auteur

Aha ça marche, je lance le système, je vous tiens au courant :)

Merci de vos réponses rapides !

EnObliO
Auteur

Une chose me chagrinne encore :
En SQL, comment je dois faire pour dire que je veux uniquement les amis de telle personne, dois-je faire quelque chose comme:

SELECT * FROM amis WHERE pseudo_exp = SESSION AND pseudo_dest = personne souhaitée OR pseudo_exp = personne souhaitée AND pseudo_dest = SESSION ???

Je dirai :

SELECT pseudo_exp, pseudo_dest
FROM amis
WHERE (pseudo_exp = personne_souhaitée AND active = 1)
    OR (pseudo_dest = personne_souhaitée AND active = 1)

Ça représente quoi "SESSION" ?
[EDIT] Ah j'ai pigé, tu voulais dire "$_SESSION['username'], un truc comme ça ?
Non ça n'a pas de sens.
Essaies toujours de penser en "Français" avant de penser en "code" :
Français : Si on veut tous les amis de Marc, il faut récupérer toutes les lignes "active" qui contiennent "Marc".
(tu vois on s'en fiche de la personne connecté).

EnObliO
Auteur

Oui SESSION voulait dire $_SESSION['username'] ^^
Je viens de terminer le système pour envoyer des demandes, anuler la demande en cours, accepter ou refuser :)
Maintenant, je m'attaque a l'affichage des amis avec ta solution

EnObliO
Auteur

Je ne comprend pas comment afficher la listes des amis du membre connecté....
J'ai essayé la requête SQL en remplaçant personne_souhaitée par la SESSION['username'] afin d'obtenir la liste de ses amis, mais lorsque je veux traiter les données en PHP, bah la....... je n'arrive pas à dire qui est l'exp et qui est le dest.
Tu vois mon problème ou u veux que je réexplique ?

Tu vois mon problème ou u veux que je réexplique ?

Je crois que je vois.

je n'arrive pas à dire qui est l'exp et qui est le dest.

Si tu veux dire, de façon général dans la boucle, c'est normal.
À chaque itération, le dest pourrait aussi bien contenir la personne souhaitée que son ami (pareil pour le exp).
Donc il ne faut pas vraiment chercher "à dire qui est l'exp et qui est le dest" puisque ça va changer à chaque itération (ou plutôt, il est possible que ça change à chaque itération).
À chaque itération, il faut vérifier :
Si le champ contient la personne souhaitée, ou son ami.

Je ne comprend pas comment afficher la listes des amis du membre connecté....
je n'arrive pas à dire qui est l'exp et qui est le dest.

Je ne vois pas du tout l'intérêt de savoir qui a fait la demande ou qui l'a reçu, si tu veux juste lister les amis d'un utilisateur.
Qu'il soit l'expéditeur ou le destinataire de la demande, ils sont quand même amis du moment que l'un des deux à confirmé la demande de l'autre, tu as donc juste faire ta requête SQL en mettant en condition qu'il soit, soit en pseudo_exp ou en pseudo_dest et que le champ active soit positif.

EnObliO
Auteur

Oui c'est ce que j'ai fais, mais c'est pas pour la requête sql que je coince, c'est au niveau de l'interprétation avec php...
Je voudrais afficher la liste de l'utilisateur connecté.

style :
Jean
Marion
Pierre
...

Et je ne veux pas que le nom de la personne connecté remonte

Beh tu ne récupères la liste des prénoms et tu boucle dessus.
J'ai un peu de mal à saisir ce sur quoi tu coinces ?..

EnObliO
Auteur

si je boucle dessus, a un moment donné il va bien falloir que je dise a php de me donner uniquement le nom qui n'est pas égal a $_SESSION['username'] et c'est la que je bloque
je ne sais pas trop comment expliquer....
vous pourriez me donner un petit exemple afin de m'aider svp ?

Tu récupères la liaste des noms, prénoms et IDs des users amis, tu boucles dessus.
Dans la boucle, tu places une condition en checkant l'ID du l'user ami et l'utilisateur connecté.

$users_list = [];
foreach ($users as $user) {
  if ($user->id !== $_SESSION['user']['id']) {
    $users_list[$user->id] = $user;
  }
}

return $users_list;

Il te faut donc avoir l'ID de l'user connecté en session. Le mieux est de stocker en session un array associatif contenant les infos de l'utilisateur connecté (id, nom, mail etc).

EnObliO
Auteur

J'ai déja tout ça stocké en session :)
Je modifie un peu ton script et je le teste, merci

EnObliO
Auteur

Hum, j'ai l'erreur
"Warning: Illegal string offset 'id'" sur la ligne "if ($user->id !== $_SESSION['nom']['id']) {"

Est-ce que $user est une instance d'une classe qui a un attribut "id" ?
si tu fais $user->id, ça veut dire que l'attribut 'id' est public. Mais c'est une très mauvaise façon de faire.
Il faudrait utiliser un getter : $user->getId().

Est-ce que 'nom' est une clé de $_SESSION ?
si oui, est-ce que cette clé est un tableau ? Et est-ce que ce tableau a une clé qui s'appelle 'id' ?

EnObliO
Auteur

$_SESSION['nom'] existe oui et $_SESSION['id'] aussi

Et pour le reste..?

EnObliO
Auteur

Comment ça le reste ?

$_SESSION['nom'] existe oui et $_SESSION['id'] aussi

$_SESSION['nom']['id'] n'a rien à voir avec $_SESSION['nom'] et $_SESSION['id']

Comment ça le reste ?

Est-ce que $user est une instance d'une classe qui a un attribut "id" ?
si tu fais $user->id, ça veut dire que l'attribut 'id' est public. Mais c'est une très mauvaise façon de faire.
Il faudrait utiliser un getter : $user->getId().

EnObliO
Auteur

Je n'ai jamais utilisé $_SESSION['nom']['id']......
De plus, je n'utilise pas $user. A vrai dire, je ne suis pas pro au niveau du PHP, instance est un terme que je ne maitrise absolument pas :/

En fait la classe dont est instancié $user à un attribut 'id' privé,
et toi tu essaies d'y accéder directement
$user->id
alors que c'est interdit par le principe d'encapsulation de la programmation orienté objet. Il faut passer par un getter.
$user->getId()

Oui je vois...

Bon c'est pas facile... Tu devrais faire une pause 1 ou 2 jours pour apprendre les bases de l'objet. Parce-qu'on patine là...

[EDIT]

Je n'ai jamais utilisé $_SESSION['nom']['id']

ah ben du coup tu as 2 erreur sur une seule ligne alors :

$user->id !== $_SESSION['nom']['id']

$user->id plante,
et $_SESSION['nom']['id'] plante.

EnObliO
Auteur

Oui je sais qu'on patine, en même temps je ne pige absolument pas les termes...
Tu veux dire les bases de la POO ?

Donc là je pense que tu devrais commencer par suivre les formations PHP disponibles sur le site, ça t'aidera car là tu donnes vraiment l'impression de ne pas du tout comprendre ce que tu fais.
https://www.grafikart.fr/formations/php-debutant | https://www.grafikart.fr/formations/programmation-objet-php

EnObliO
Auteur

Et c'est pas qu'une impression...
Merci pour les liens, je regarde

Bonjour,

Donc, si j'ai bien tout compris, tu as 2 tables :

la table membres

id
pseudo

la table amis

id_invitation
pseudo_exp
pseudo_dest
date_invitation
date_confirmation
active

Il s'agit d'une relation one to many car un utilisateur peut avoir plusieurs amis, c'est pour cela que l'on stocke la liste des amis dans une table à part.

La requête pour afficher la liste des amis d'un membre serait :

SELECT m2.id, m2.pseudo
FROM membres m1
INNER JOIN amis a ON m1.pseudo = a.pseudo_exp OR m1.pseudo = a.pseudo_dest -- on récupère les ID des amis
INNER JOIN membre m2 ON (m2.pseudo = a.pseudo_exp OR m2.pseudo = a.pseudo_dest) AND m2.pseudo != m1.pseudo -- on récupère les infos des amis
WHERE m1.pseudo = $pseudo_membre
EnObliO
Auteur

Bonjour fabsgc,
C'est exactement ce que je chercais a faire, de plus, j'apprends a utiliser la POO,
Mais juste une question concernant la requête SQL, a quoi correspond m1 et m2 ??

EnObliO
Auteur

Ah oui je vois, merci beaucoup pour ta réponse !!!!