简体   繁体   中英

Foreach loops within a foreach loop

I have a news steam being pulled from a MySQL table displaying things like headline, story and date. These news stories are generated from a PHP foreach loop and works fine.

I have two more MySQL tables, one for images and one for videos. These tables have a column called news_id that link with the news table's unique field. The idea is each news story will automatically display any videos or images attached too it.

The code for this doesn't work correctly though - eg if a story has 3 matching images and one video it actually outputs that video 3 times, one next to each picture. Same if there were 5 videos and one picture, it would show that picture 5 times.

The code worked ok when it was just pulling images next to the news but since I added the video table too the problem started. I think I need to rewrite the queries and foreach loop but have no idea how. My guess is that I need two foreach loops within the main foreach - one for images and one for videos.

How I want it to work is:

Headline, Date and Story pulled for news table

any photo_url's pulled from image table

any video_url's pulled from video table

then the next headline and so on. Can anyone help me structure this?

For reference this is the current query used:

$sql = 'SELECT headline, story, DATE_FORMAT(date, "%d-%M-%Y") AS Displaydate, name, logo, tpf_parks.park_id, url, alt, description, credit, location
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id 
LEFT JOIN tpf_images ON tpf_news.news_id = tpf_images.news_id 
LEFT JOIN tpf_videos ON tpf_news.news_id = tpf_videos.news_id 
ORDER BY date DESC' ;
$result = $pdo->query($sql);

and current php used:

$sLastStory = '';
foreach ($result AS $row)
{
    $sStory = $row['headline'] . $row['story'];
    if (strcasecmp($sStory, $sLastStory) != 0)
    {
        if (!empty($sLastStory))
        {
            print('<hr>' . PHP_EOL);
        }
        $sLastStory = $sStory;


        printf('<h2>%s</h2>' . PHP_EOL, $row['headline']);

        printf('<h3><a href="parknews.php?park_id=%s">
        %s</a> - %s</h3>' . PHP_EOL, $row['park_id'], $row['name'], $row['Displaydate']);

        printf('<p>%s</p>' . PHP_EOL, $row['story']);
    }

if(!empty($row['url'])){   
printf('
<a href="/images/%s%s.jpg" rel="lightbox[%s]" title="%s - Credit - %s" >
<img src="/images/%s%s-thumb.jpg" style="max-height: 250px; max-width: 250px" alt="%s"/></a>' . PHP_EOL, $row['url'], $row['alt'], $row['headline'],  $row['description'],$row['credit'], $row['url'], $row['alt'], $row['alt'] );
}

if(!empty($row['location'])){   
printf('<iframe width="640" height="360" src="%s" allowfullscreen></iframe>' . PHP_EOL, $row['location'] );
}

}

How can I make this code work correctly to display the data as I want? But as i said I think it all needs a total rewrite.

You could use GROUP_CONCAT . This will return a concatenated string, which you can then explode() . This will make it so you return 1 row per headline, so you can easily group your images and videos.

$sql = 'SELECT headline, story, DATE_FORMAT(date, "%d-%M-%Y") AS Displaydate, 
        name, logo, tpf_parks.park_id, 
        GROUP_CONCAT(url) as url, GROUP_CONCAT(alt) as alt, GROUP_CONCAT(description) as description, 
        GROUP_CONCAT(credit) as credit, GROUP_CONCAT(DISTINCT location) as location
FROM tpf_news
INNER JOIN tpf_parks ON tpf_news.park_id = tpf_parks.park_id 
LEFT JOIN tpf_images ON tpf_news.news_id = tpf_images.news_id 
LEFT JOIN tpf_videos ON tpf_news.news_id = tpf_videos.news_id 
GROUP BY tpf_images.news_id, tpf_videos.news_id 
ORDER BY date DESC' ;
$result = $pdo->query($sql);

Then in your loop, use explode() on each of the columns that were concatenated -

if(!empty($row['url'])){ 
   $url=explode(',',$row['url']);
   $alt=explode(',',$row['alt']);
   $description=explode(',',$row['description']);
   $credit=explode(',',$row['credit']);

   for($i=0;$i<count($url);$i++){
     printf('
        <a href="/images/%s%s.jpg" rel="lightbox[%s]" title="%s - Credit - %s" >
        <img src="/images/%s%s-thumb.jpg" style="max-height: 250px; max-width: 250px" alt="%s"/></a>' . PHP_EOL, $url[$i], $alt[$i], $row['headline'],  $description[$i],$credit[$i], $url[$i], $alt[$i], $alt[$i] );
   }
}

if(!empty($row['location'])){  
   $location=explode(',',$row['location']);
   for($j=0;$j<count($location);$j++){
        printf('<iframe width="640" height="360" src="%s" allowfullscreen></iframe>' . PHP_EOL, $location[$j] );
   }
}

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