简体   繁体   中英

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!

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

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);
    }
}

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']);
 }

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);
}

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM