Page 1 of 1

How do I call a nested foreach with this code?

Posted: Wed Feb 14, 2007 9:32 am
by blepoxp
Greetings,

I have some php code that looks like this:

Code: Select all

mssql_select_db($database, $dbconnect);
$query = "SELECT TOP 10 Res.ResourceID, Res.Title AS Res_Title, Res.ShortBlurb, Res.Created, Cat.Title AS Cat_Title, Doc.Title AS Doc_Title, Doc.Location AS Doc_Location ";
$query .= "FROM DA_Resource Res, DA_Category Cat, DA_Document Doc ";
$query .= "WHERE Res.ResourceID = Doc.ResourceID ";
$query .= "AND Cat.CategoryID = Res.CategoryID ";
$result = mssql_query( $query, $dbconnect );

while ($line = mssql_fetch_assoc($result))
        {
            $return[] = $line;
        }

$output = "<html><body><ul>";

foreach ($return as $line) 
{ $output .= "<li>$line[Res_Title]<ul>
			  		<li>Category: $line[Cat_Title]</li>
			  		<li>Date Created: $line[Created]</li>
			  		<li>$line[Doc_Location]</li>
			  		</ul>
			  </li>";}

$output .="</ul></body></ul>";
echo $output;
The output results in this:
  • Hope In The Midst Of Suffering
    • Category: 1 Peter
    • Date Created: May 10 2004 8:50AM
    • \Resource_16\Hope_In_The_Midst_Of_Suffering.pdf
  • How Can I Give Glory To God?
    • Category: 1 Peter
    • Date Created: May 10 2004 9:03AM
    • \Resource_17\How_Can_I_Give_Glory_To_God.pdf
  • How To Smile When You Suffer For Jesus
    • Category: 1 Peter
    • Date Created: May 10 2004 9:05AM
    • \Resource_18\How_To_Smile_When_You_Suffer_For_Jesus.pdf
  • What A Life
    • Category: 1 John
    • Date Created: May 10 2004 9:29AM
    • \Resource_20\what a life-outline.pdf
  • What A Life
    • Category: 1 John
    • Date Created: May 10 2004 9:29AM
    • \Resource_20\what a life-sermon.pdf
  • When Men Call God A Liar
    • Category: 1 John
    • Date Created: May 10 2004 10:23AM
    • \Resource_21\When Men Call God A Liar-sermon.pdf
  • When Men Call God A Liar
    • Category: 1 John
    • Date Created: May 10 2004 10:23AM
    • \Resource_21\When Men Call God A Liar-outline.pdf
  • When Men Call God A Liar
    • Category: 1 John
    • Date Created: May 10 2004 10:23AM
    • \Resource_21\Akin, Daniel - When Men Call God A Liar.mp3
  • Know And Obey
    • Category: 1 John
    • Date Created: May 10 2004 10:31AM
    • \Resource_22\Know And Obey-Sermon.pdf
  • Know And Obey
    • Category: 1 John
    • Date Created: May 10 2004 10:31AM
    • \Resource_22\Know And Obey-outline.pdf
As you can see, Some Resources (like 'what a life') have more than one file associated with them in the database. When I loop through the array, my current code will repeat the resource name, category, and date created for every document associated with that resource.

The question is, How would I go about listing resources with more than one document only once with each document listed below it?

I am assuming I need to either create my array differently or create some type of nested loop. I'm a newbie, however, and can not figure this out with google/o'reilly.

Could somebody help? Thanks.

Posted: Wed Feb 14, 2007 9:36 am
by feyd
Take a look at the first two links found in Useful Posts.

Posted: Wed Feb 14, 2007 9:39 am
by blepoxp
Thanks for the direction, but I've been to these resources much of the day yesterday and today just to get the code to where it is now. Although I'm continuing to look, I was hoping somebody here my be able to give me some constructive feedback based on my specific problem.

Posted: Wed Feb 14, 2007 9:43 am
by feyd
Those posts are on your specific problem whether you realize it or not.

Posted: Wed Feb 14, 2007 9:44 am
by blepoxp
I really do appreciate your help and am currently reading.
Just to confirm, are you talking about this post: viewtopic.php?t=37448

Posted: Wed Feb 14, 2007 10:10 am
by blepoxp
Okay,
I understand if you don't have time to help me through this with my specific problem, but I'm not going to figure it out on my own. Would anyone be interested in walking me through this? I acknowledge that my php is a work in progress, so if you're generally unsympathetic to such ignorance, consider yourself forewarned. Thanks :)

Posted: Wed Feb 14, 2007 3:26 pm
by blepoxp
Okay,
Here's some update code, but it's giving me a "unexpected $end" error on the last line of code:

Could you tell me where to look for errors (I'm sure they abound).

Code: Select all

$query = "SELECT TOP 10 Res.ResourceID , Res.Title AS Res_Title, Res.ShortBlurb, Res.Created, Cat.Title AS Cat_Title ";
$query .= "FROM DA_Resource Res, DA_Category Cat, DA_Document Doc ";
$query .= "WHERE Res.ResourceID = Doc.ResourceID ";
$query .= "AND Cat.CategoryID = Res.CategoryID ";
$resources = mssql_query( $query, $dbconnect );

$query2 = "SELECT TOP 10 Res.Title, Doc.Title AS Doc_Title, Doc.Location AS Doc_Location ";
$query2 .= "FROM DA_Resource Res, DA_Document Doc ";
$query2 .= "WHERE Res.ResourceID = Doc.ResourceID ";
$documents = mssql_query( $query2, $dbconnect );

$cache1 = array();
while ($row = mssql_fetch_assoc($resources))
        {
            $cache1[] = $row;
        }

$cache2 = array();
while ($row = mssql_fetch_assoc($documents))
		{
			$cache2[] =$row;
		}
        
$output = "<html><body><ul>";

foreach ($cache1 as $row) 
{ $output .= "<li>$row[Res_Title]<ul>
			  		<li>Category: $row[Cat_Title]</li>
			  		<li>Date Created: $row[Created]</li>";
			  	foreach ($cache2 as $row)
			  		{ $output .= "<li>$row[Doc_Title] $row[Doc_Location]</li>
		  				}</ul>";
			  		
			  $output .="</li>"; }

$output .="</ul></body></ul>";
echo $output;

?>

Posted: Wed Feb 14, 2007 3:32 pm
by Kieran Huggins
you need to close your last foreach

Posted: Thu Feb 15, 2007 9:06 am
by blepoxp
Thank you, Kieran. That helped.

I have another question now. Is it possible to compare variables from two different caches located in two separate foreach statements? Specifically, where I have 'cache1varible' and 'cache2varible' located below?

Code: Select all

$cache1 = array();
while ($row = mssql_fetch_assoc($resources))
        {
            $cache1[] = $row;
        }

$cache2 = array();
while ($row = mssql_fetch_assoc($documents))
		{
			$cache2[] =$row;
		}
        
$output = "<html><body><ul>";

foreach ($cache1 as $row) 
{ $output .= "<li>$row[Res_Title]<ul>
			  		<li>Category: $row[Cat_Title]</li>
			  		<li>Date Created: $row[Created]</li>";
			  	foreach ($cache2 as $row)
			  		{ if ($row[ResIDfromcache2] == $row[ResIDfromcache1]) {$output .= "<li>$row[Doc_Title] $row[Doc_Location]</li>";}
			  		
			   }$output .="</ul>"; }
Thanks.

Posted: Thu Feb 15, 2007 9:23 am
by feyd
$row is being overridden in the interior foreach. Also, always use quotes when referencing named elements (e.g. $foo['bar']) when not in complex string contexts.

Posted: Thu Feb 15, 2007 9:28 am
by kingconnections
You need to call the nested loop data variable something different that $row. You can use anything here ie. $row2. If that variable is still an active variable and u assign it again in a nested loop it will get confused.

Code: Select all

$cache1 = array(); 
while ($row = mssql_fetch_assoc($resources)) 
        { 
            $cache1[] = $row; 
        } 

$cache2 = array(); 
while ($row = mssql_fetch_assoc($documents)) 
                { 
                        $cache2[] =$row; 
                } 
        
$output = "<html><body><ul>"; 

foreach ($cache1 as $row) 
{ $output .= "<li>$row[Res_Title]<ul> 
                                      <li>Category: $row[Cat_Title]</li> 
                                      <li>Date Created: $row[Created]</li>"; 
                                foreach ($cache2 as $row2) 
                                      { if ($row2[ResIDfromcache2] == $row[ResIDfromcache1]) {$output .= "<li>$row2[Doc_Title] $row2[Doc_Location]</li>";} 
                                      
                           }$output .="</ul>"; }

Also this allows for you to compare the outer loop to the inner loop by having 2 seperate variables to hold the data :)!

ie $row[blah] == $row2[blah]

Posted: Thu Feb 15, 2007 9:45 am
by blepoxp
Thanks again. That worked great.
I now have to figure out why I'm getting 3 instances of a resource if it has 3 documents associated with it and 2 instances of a resource if it has 2 documents with it. I think I saw something about a unique condition in either php or sql. I'll search it out. Maybe someone could tell me if I'm going in the wrong direction. (I really do enjoy learning php/sql. I just wish I could do it on my own terms, rather than working out a specific app for my employer).

Posted: Thu Feb 15, 2007 9:57 am
by blepoxp
SELECT DISTINCT

That wasn't too hard.
Again, thank so much to feyd, kieran, and kingconnections for your help. I believe this topic is officially closed (although I'm sure I'll be back).

Here's the final outcome for those reading after the fact:

Code: Select all

<?php
//Omitted DB Connections//
$query = "SELECT DISTINCT TOP 10 Res.ResourceID AS Res_ID, Res.Title AS Res_Title, Res.ShortBlurb, Res.Created, Cat.Title AS Cat_Title ";
$query .= "FROM DA_Resource Res, DA_Category Cat, DA_Document Doc ";
$query .= "WHERE Res.ResourceID = Doc.ResourceID ";
$query .= "AND Cat.CategoryID = Res.CategoryID ";
$resources = mssql_query( $query, $dbconnect );

$query2 = "SELECT TOP 10 Res.ResourceID AS Res_ID, Res.Title, Doc.ResourceID AS Doc_ResID, Doc.Title AS Doc_Title, Doc.Location AS Doc_Location ";
$query2 .= "FROM DA_Resource Res, DA_Document Doc ";
$query2 .= "WHERE Res.ResourceID = Doc.ResourceID ";
$documents = mssql_query( $query2, $dbconnect );

$cache1 = array();
while ($row = mssql_fetch_assoc($resources))
        {
            $cache1[] = $row;
        }

$cache2 = array();
while ($row = mssql_fetch_assoc($documents))
		{
			$cache2[] =$row;
		}
        
$output = "<html><body><ul>";

foreach ($cache1 as $row)
{ $output .= "<li>$row[Res_Title]<ul>
                                      <li>Category: $row[Cat_Title]</li>
                                      <li>Date Created: $row[Created]</li>";
                                foreach ($cache2 as $row2)
                                      { if ($row2['Doc_ResID'] == $row['Res_ID']) {$output .= "<li>$row2[Doc_Title] $row2[Doc_Location]</li>";}
                                     
                       		  		
			   }$output .="</ul>"; }

$output .="</li></ul></body>";
echo $output;

?>