angusVen
angusVen

Reputation: 3

Mysqli_query inside of a foreach loop

I'm having trouble with a mysqli_query from inside a foreach loop, I'm getting a string from a table first, then separating that into an array. Then I try looping through the array and calling a query inside the loop.

$langs_result = mysqli_query($con, "SELECT Languages FROM users WHERE Username = '$username'");

    $row = mysqli_fetch_assoc($langs_result);

    $langs = $row['Languages'];
    $userLangs = str_replace(" ","",$langs);
    $userLangs = explode(",",$langs);
    print_r($userLangs);
    $posts = array();

    foreach($userLangs as $lang){
        echo "$lang <br>";
        $sql = "SELECT * FROM posts WHERE Language = '$lang'";
        $getLangPosts = mysqli_query($con, $sql);
        array_push($posts, mysqli_fetch_assoc($getLangPosts));
    }

    print_r($posts);

for this user the langusges are German, Italian, Danish, and English, but the $posts array only contains the first post found from the first language (German), can anybody help? I am trying to get all of the posts for each language in the $userLangs array.

It's going through the foreach loop okay as the $lang variable that's echoed changes each time but the query still isn't working properly.

Thanks for the help!

Upvotes: 0

Views: 5651

Answers (5)

Kickstart
Kickstart

Reputation: 21513

You an avoid multiple queries by doing a JOIN, using FIND_IN_SET to match on your comma separated list. You probably need to use REPLACE to get rid of the extra spaces in the comma separated list as well.

Then you can just loop around to display the data, displaying the language on change of language:-

<?php

$sql = "SELECT a.Languages AS user_languages, 
                b.*
        FROM users a
        LEFT OUTER JOIN posts b
        ON FIND_IN_SET(b.Language, REPLACE(a.Languages, ' ', ''))
        WHERE a.Username = '$username'
        ORDER BY b.Languages";

$langs_result = mysqli_query($con, $sql);

if($row = mysqli_fetch_assoc($langs_result))
{
    print_r(explode(', ', $row['user_languages']));
    $prev_langauge = '';
    while($row = mysqli_fetch_assoc($langs_result))
    {
        if ($prev_langauge != $row['Languages'])
        {
            if ($prev_langauge != '')
            {
                print_r($posts);
            }
            $posts = array();
            echo $row['Languages']."<br>";
            $prev_langauge = $row['Languages'];
        }
        array_push($posts, mysqli_fetch_assoc($row));
    }
    if ($prev_langauge != '')
    {
        print_r($posts);
    }
}

Upvotes: 1

Master Yoda
Master Yoda

Reputation: 531

select posts.* from posts
left join users on users.language=posts.language
where users.username='your_desiredusername'
group by users.language;

Just try to run this as a single query by filling the username no need of multiple queries

Upvotes: 1

Alex Andrei
Alex Andrei

Reputation: 7283

UPDATE
See this code:

<?php

$langs_result = mysqli_query($con, "SELECT Languages FROM users WHERE Username = '$username'");

$row = mysqli_fetch_assoc($langs_result);

$langs = $row['Languages'];

// $langs = 'German, Italian, Danish, French'; added this to run the test

// $userLangs = str_replace(" ","",$langs); this is not needed, see the explode below
$userLangs = explode(", ",$langs);

foreach($userLangs as $lang){
    echo $lang;
    $sql = "SELECT * FROM posts WHERE Language = '$lang'";

    $getLangPosts = mysqli_query($con, $sql); // this is the result of the select *
    while($post = mysqli_fetch_assoc($getLangPosts)){ // iterate over all the results
        $postField = $post["yourChoiceField..say..Title"]; // get something from each row
        array_push($posts, $title); // push into array
    }
}

print_r($posts);

Since the initial select is based on username I don't believe the first loop is needed so your code was on the right track.
A second loop was needed to iterate over the posts though and a field to populate the $posts array.


You need to perform mysqli_fetch_assoc in a loop

$langs_result = mysqli_query($con, "SELECT Languages FROM users WHERE Username = '$username'");

while($row = mysqli_fetch_assoc($langs_result)){

    $langs = $row['Languages'];

    $userLangs = str_replace(" ","",$langs); // i don't get why you are doing this though
    $userLangs = explode(",",$langs);
    print_r($userLangs);

    $posts = array();

    foreach($userLangs as $lang){
        echo "$lang <br>";
        $sql = "SELECT * FROM posts WHERE Language = '$lang'";
        $getLangPosts = mysqli_query($con, $sql);
        array_push($posts, mysqli_fetch_assoc($getLangPosts));
    }

    print_r($posts);
}

It would help to know how what the select query actually returns.

Upvotes: 0

Harshit
Harshit

Reputation: 5157

You need to loop the inner query to get the column data

foreach($userLangs as $lang){
        echo "$lang <br>";
        $sql = "SELECT * FROM posts WHERE Language = '$lang'";
        $getLangPosts = mysqli_query($con, $sql);

        while($row1 = mysqli_fetch_assoc($getLangPosts))
              array_push($posts, $row1['YOUR_COLUMN_NAME']);
    }

OR you should use IN clause instead of loop

$langs_result = mysqli_query($con, "SELECT Languages FROM users WHERE Username = '$username'");

while($row = mysqli_fetch_assoc($langs_result)){

$langs = $row['Languages'];
$userLangs = str_replace(" ","",$langs);
$userLangs = explode(",",$langs);
print_r($userLangs);
$posts = array();

$sql = "SELECT * FROM posts WHERE Language IN ('".implode(',',$userLangs)."')";
        $getLangPosts = mysqli_query($con, $sql);

        while($row1 = mysqli_fetch_assoc($getLangPosts))
              array_push($posts, $row1['YOUR_COLUMN_NAME']);
 }

Upvotes: 0

Muhammad Bilal
Muhammad Bilal

Reputation: 2124

mysqli_fetch_assoc only fetches one row on each call you need to use it like this:

while ($row_new = mysqli_fetch_assoc($getLangPosts)){
   array_push($posts, $row_new);
}

Upvotes: 0

Related Questions