Log in

View Full Version : Problems with loops inside loops



Beverleyh
07-14-2010, 11:12 AM
I'm getting in a bit of a pickle with loops in php.

I'm using this code to generate a dynamic lists from .php pages in 3 sub-folders at my website root. This list will become a menu (once I've got it working).



<?php

$rooturl = '/home/www/mywebsite.com/';

$subfolders_path = opendir($rooturl);
while (false !== ($folder = readdir($subfolders_path)) )
{
if( (is_dir($rooturl.$folder)) && (substr($folder,0,1) != '.') )
{
$folders = explode (' ', $folder);
foreach ($folders as $sub_folder)
{

$dh = opendir($rooturl.$sub_folder);
echo '<ul id="'.$sub_folder.'" class="menu">';
while (false !== ($file = readdir($dh)) )
{
if (strpos($file, '.php',1)) // only include files with .php extension
{
if ( $file!='.' && $file!='..' )
{
$file_array[] = $file;
}
}
}
foreach ($file_array as $value)
{
echo '<li class="menu">'.$value.'</li>';
}
echo '</ul><br style="clear:both"/>';
closedir($dh);

}
}
}
closedir($subfolders_path);
?>

The output is this example here: http://www.jemcon.org/process_scripts/test/menu_test.php

As you can see, the script is repeating the php files from previously read sub-folders and including them in the following lists - see how the first list just displays colours from the "colour" folder but the second list then continues to display the previously read colours and adds them to the list for "animals", while the third list adds both to the last "drinks" list.

All I want is the script to generate this output (mocked-up a static HTML file as an example): http://www.jemcon.org/process_scripts/test/menu_test2.php

I know it's the looping which is off but I'm not sure how to fix it.

Can somebody help me please?

djr33
07-14-2010, 04:08 PM
That's a lot of code and it's hard to guess without testing.
But here are two things that stand out as odd to me:

$folders = explode (' ', $folder);
Why are you exploding? $folder is the result of a function that generates strings.
I believe you can skip this and skip this loop at well: foreach ($folders as $sub_folder). Actually, instead of skipping it, you may want to replace it with a while + readdir() loop.
Right now since explode probably is generating a one-item array, it may appear to be working, but if your folder name is "Untitled Folder" then it will try to view both "untitled" and "folder". So that can't be right.

$file_array[] = $file;
I believe this line is generating the problems with repeating values. The first time this is used, it creates a new array and adds the first $file. Then every next time it just adds a new value. So each repeated loop here already has a value set for this. I believe all you need to do to fix it is add $file_array = array(); immediately before your while loop:
$file_array = array(); //(re)set this as empty
while (false !== ($file = readdir($dh)) )
That will reset the array with each loop rather than still adding to the old values.
In general, this is important: always pre-set arrays and other complex variables within loops so that nothing persists through the various cycles and also just so that you know what to expect from the variable directly rather than hoping it all does what you want within the loop.

Beverleyh
07-14-2010, 06:56 PM
$file_array = array(); //(re)set this as empty
while (false !== ($file = readdir($dh)) )
That sorted it!

I've been looking at the code for 2 days and I can't believe I couldnt get my head around something that now looks obvious. Maybe I just couldn't see the woods for looking at the trees!

BTW - all the sub-folder names have spaces replaced with underscores during creation so the explode function works fine under these circumstances.

Thanks for your help Daniel.

djr33
07-15-2010, 07:40 AM
I'm glad it works.

RE: BTW: I still don't see the purpose of this function. If a space never occurs in the name, then why are you exploding it? You don't need any sort of loop here, because a one-item loop will just do one rotation... perhaps I'm missing something?