Page 1 sur 2

Foreach imbriqués

Posté : 02 mars 2013, 01:11
par damien_55
Bonjour a tous,

J'ai 2 foreach imbriqués dont le deuxième me sort des résultats incohérents. alors que les deux individuellement marche trés bien. je ne comprends pas pourquoi ?

Voici mon code en bride
$feeds = mysql_query("(SELECT
etc..
while($feed = mysql_fetch_array($feeds)) {
etc..
$nouvelle = array('local_news_user_id'=>$feed['local_news_user_id']
etc..
foreach($content['feeds'] as $feed) {
if(is_numeric($feed['local_news_user_id']))	
echo '.....
Ici, j'insere mon deuxieme foreach qui recupère une valeur du premier
$news_replys = mysql_query("SELECT ...... WHERE id='".$feed['local_news_user_id']."' 
while($news_reply = mysql_fetch_array($news_replys)) {
etc...
$nouvelle1 = array(
	'news_reply_id'=>$news_reply['news_reply_id']
etc...
foreach($content1['news_replys'] as $news_reply) {
etc..
if(is_numeric($news_reply['news_reply_id']))
etc..
echo '<


je referme le tout.

En fait le deuxième foreach m'envoie des résultat même quand il n'y a pas de donné par rapport à la requete $news_replys ???

Comprends pas, alors que seul, ça marche trés bien.

Re: Foreach imbriqués

Posté : 02 mars 2013, 11:29
par xTG
Moi je vois un souci de conception.
Pourquoi ne pas utiliser une requête avec jointure ?
Une seule requête, une seule boucle, toutes les informations liées.

http://sqlpro.developpez.com/cours/sqlaz/jointures/

Re: Foreach imbriqués

Posté : 02 mars 2013, 15:12
par damien_55
J'ai lu la doc.

Pour retourner tous mes résultats, j'ai mis un UNION entre mes 2 requetes.

Mais je ne suis pas du tout satisfait du résultat. ça marche mais c'est pas travaillable du fait que les champs prennent la nom de la première requete.

Je ne vois pas la logique à adopter pour avoir une requete propre si je mets des WHERE table1.id=table2.id AND .... etc... dans ma requete cela me genere que les résultats qui sont vérifiés par la condition. Alorq que j'ai besoin de tous les résultats de ma première requete et de la deuxieme si il existe.

Re: Foreach imbriqués

Posté : 02 mars 2013, 16:28
par yann18
Je ne vois pas la logique à adopter pour avoir une requete propre si je mets des WHERE table1.id=table2.id AND .... etc... dans ma requete cela me genere que les résultats qui sont vérifiés par la condition. Alorq que j'ai besoin de tous les résultats de ma première requete et de la deuxieme si il existe
une jointure externe(left join ou right join) pourrait être envisagée pour répondre à ce que tu veux faire.

Re: Foreach imbriqués

Posté : 02 mars 2013, 18:28
par xTG
Comme le souligne yann18 une requête à jointure va exactement te retourner ce que tu souhaites.
Avec LEFT ou RIGHT comme type de jointure tu prends tous les enregistrements d'une table, en considérant les conditions WHERE lui étant attribuée, puis tu lui joins (un UNION mais au milieu de la liste des résultats en gros) les résultats de la seconde table qui respectent la/les condition(s) de jointure.

Re: Foreach imbriqués

Posté : 02 mars 2013, 18:42
par damien_55
Merci yann18 & XTG.

J'ai mis ça
SELECT local_news_users.id as local_news_user_id, local_news_users.subject, local_news_users.brief, local_news_users.city_id, local_news_users.user_id as id_user_post, 
local_news_users_reply.id_local_new_reply as news_reply_id, local_news_users_reply.brief_reply, local_news_users_reply.user_id_reply
FROM local_news_users 
LEFT JOIN local_news_users_reply
ON local_news_users.id = local_news_users_reply.id_local_new_reply
Le dernier problme qui se pose c'est de récupérer les nom & prenom de l'utilisateur dans une autre table.

Quand je rajoute
FROM users, local_news_users...
WHERE local_news_users.user_id=users.id
ça ne marche pas. mais bon ça avance... :D

Re: Foreach imbriqués

Posté : 02 mars 2013, 21:00
par damien_55
je suis complétement bloqué je ne comprends pas

1 -pourquoi ma requete sql sur 2eme foreach marche si elle est éxécuter seule et si je la met dans mon premier script ça me retourne n'importe quoi ??

Re: Foreach imbriqués

Posté : 02 mars 2013, 22:02
par yann18
pour récupérer le nom et le prénom il faut enchaîner une nouvelle jointure sur les tables local_news_users et users:
SELECT local_news_users.id AS local_news_user_id, local_news_users.subject, local_news_users.brief, local_news_users.city_id, local_news_users.user_id AS id_user_post, 
local_news_users_reply.id_local_new_reply AS news_reply_id, local_news_users_reply.brief_reply, local_news_users_reply.user_id_reply,u.nom, u.prenon
FROM local_news_users
LEFT JOIN local_news_users_reply
ON local_news_users.id = local_news_users_reply.id_local_new_reply
left join users u on local_news_users.user_id=u.id

-dans le cas de la jointure(left join) entre local_news_users et users, toutes les lignes de local_news_users seront retournées y compris celles qui ne contiennent aucun user(user_id, d'ou user_id sera=null) .

-dans le cas de la jointure( join) entre local_news_users et users,ne seront retournées que les lignes communes entre les 2 tables.

tu peux essayer cette requête au niveau de la console mysql ou sous phpmyadmin.

Re: Foreach imbriqués

Posté : 02 mars 2013, 23:32
par damien_55
Merci Yann. J'avance.

Maintenant, j'arrive à ça
SELECT local_news_users.id AS local_news_user_id, local_news_users.subject, local_news_users.brief, local_news_users.city_id, local_news_users.user_id AS id_user_post, 
local_news_users_reply.id_local_new_reply AS news_reply_id, local_news_users_reply.brief_reply, local_news_users_reply.user_id_reply,
u.id, u.nom, u.prenom,
s.id, s.nom as reply_user_nom, s.prenom as reply_user_prenom
FROM local_news_users
LEFT JOIN local_news_users_reply
ON local_news_users.id = local_news_users_reply.id_local_new_reply
LEFT JOIN users_site u ON local_news_users.user_id=u.id
LEFT JOIN users_site s ON local_news_users_reply.user_id_reply=s.id
Le truc maintenant c'est que je ne vois pas comment construire ma boucle Foreach car dans mon retour de console j'ai par exemple

Pour un sujet dans la table local_news_users et 2 replys dans local_news_users_reply (ce qui veut dire qu'un sujet a été posté et que 2 personnes ont répondu),

j'obtiens dans ma console 2 lignes
- une avec l'id_sujet, le sujet et le reply_1
et l'autre avec l'id_sujet, le sujet et le reply_2

Ce que je veux afficher, c'est

le sujet
Reply_1
Reply_2

Je ne sais pas comment faire ?

Re: Foreach imbriqués

Posté : 03 mars 2013, 13:04
par xTG
Il faut faire un peu de conditionnel pour traiter deux lignes en trois fois. :)
$array = array( 
  0 => array( 'id' => 1, 'idCat' => 1, 'titreCat' => 'maCat', 'titre' => 'titre 1'),
  1 => array( 'id' => 2, 'idCat' => 1, 'titreCat' => 'maCat', 'titre' => 'titre 2'),
  2 => array( 'id' => 3', 'idCat' => 2, 'titreCat' => 'cat 2', 'titre' => 'titre 3')
);
$idCat = 0;
foreach( $array as $els){
  if( $idCat != $els['idCat'] ){
    echo '<h1>' . $els['titreCat'] . '</h1>';
    $idCat = $els['titreCat'];
  }

  echo $els['titre'] . '<br />';
}
<h1>maCat</h1>
titre 1<br />
titre 2<br />
<h1>cat 2</h1>
titre3<br />

Re: Foreach imbriqués

Posté : 03 mars 2013, 14:51
par damien_55
Je ne m'en sors pas trop :(

Est ce normal qu'avec cette requete
SELECT local_news_users.id AS local_news_user_id, local_news_users.subject, local_news_users.brief, local_news_users.city_id, local_news_users.user_id AS id_user_post, 
local_news_users_reply.id_local_new_reply AS news_reply_id, local_news_users_reply.brief_reply, local_news_users_reply.user_id_reply,
u.id, u.nom, u.prenom,
s.id, s.nom AS reply_user_nom, s.prenom AS reply_user_prenom
FROM local_news_users
LEFT JOIN local_news_users_reply
ON local_news_users.id = local_news_users_reply.id_local_new_reply
LEFT JOIN users_site u ON local_news_users.user_id=u.id
LEFT JOIN users_site s ON local_news_users_reply.user_id_reply=s.id
J'obtienne seulement 2 lignes dans ma console

- une avec l'id_sujet, le sujet et le reply_1
et l'autre avec l'id_sujet, le sujet et le reply_2

alors que dans mes tables

dans la table sujet, j'ai 1 sujet
et dans la table reply, j'ai 2 entrés en rapport avec l'id du sujet ???

Re: Foreach imbriqués

Posté : 03 mars 2013, 21:29
par xTG
Relis le lien que je t'ai donné plus haut, tu n'as à priori aucune idée de ce qu'est une jointure. :)

Re: Foreach imbriqués

Posté : 03 mars 2013, 22:03
par damien_55
J'ai relu, en fait ce qui me conviendrait le plus, c'est une jointure comme
SELECT *
FROM T_TITRE UNION JOIN T_TYPE
sauf que je suis en mysql 5.1.41 et cette fonction n'existe pas dans cette version. :?

Re: Foreach imbriqués

Posté : 04 mars 2013, 13:32
par damien_55
bah non, j'y arrive pas :(

Aprés 4 jours d'essai, je ne saisis toujours pas pourquoi le deuxieme foreach me retourne pas exactement ce que je veux.

pour faire simple, j'ai 2 bases.

Une pour les topic avec l'id, id_user, subject, message
et l'autre pour les reply avec id, id_topic, user_reply, message_reply.

Ce que je veux faire, un wall avec les 10 premiers topic et les reply qui vont avec.

1, je selectionne mes topic avec un select que je stoke dans un array avec un while.
pour l'affichage, je fait un foreach.

ça ça marche.

dans ma cette boucle, je recupere l'id du topic.

et refais un select que je stoke dans un array avec un while
avec dans mon select une clause where reply.id_topic=topic.id

(tester seule sur phpmyadmin ça marche.)

Je refais un foreach pour l'affichage pour afficher tous les reply.

Et là ça part en vrille, il m'affiche 3 ou 4 résultats alors que ma clause where devrait le limiter juste au résultats voulus.

??

Re: [RESOLU] Foreach imbriqués

Posté : 04 mars 2013, 16:39
par xTG
Ce que tu veux faire correspond tout à fait à ce qu'on t'a proposé plus haut.
Tu veux du X vers Y, donc LEFT JOIN ou RIGHT JOIN.

N.B : INNER JOIN est une jointure interne, donc d'une table sur cette même table... Et donc pas sur deux tables différentes.

Et concernant ton code à base de foreach, si tes requêtes fonctionnent sous phpmyadmin c'est donc un problème de code.
Et là on peut pas vraiment t'aider vu que tu ne nous montres que des bribes sans intérêt. :)