Need to stop echoing a comma at the end of a while loop

I am redesigning a site (located here) with a rotating image banner, and I want to use php to auto update the links to the new images. That way, once new images are placed in the directory, they will automatically be displayed on the web site, without having to update an html file with the new links to the new images.

I’ve setup a while loop



if ($handle = opendir('banner')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            echo '["banner/' . $file . '"],' . "\
";
        }
    }
    closedir($handle);
}


and it works great, but I am having a problem with the last item not needing a comma after the close bracket. If the last item has a comma, then the script won’t run (only in IE does this happen…figures it would just be in IE). So I need a way to not echo a comma once the loop gets to the last item in the directory, but i am lost on how to accomplish this.

Put the list into a string and trim the last comma :slight_smile:


$str = '';
if ($handle = opendir('banner')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            $str .= '["banner/' . $file . '"],' . "\
";
        }
    }
    closedir($handle);
} 

$str = rtrim($str, ',');

Thanks spikeZ for the fast reply! I tried your suggestion, but all I get is a blank page. Here’s a link to my php file, so you can see the output; and [URL=“http://covschool.org/new/test.html”]here’s a link to the php code in an html file

You need to echo the $str variable so it shows on the page.


$str = '';
if ($handle = opendir('banner')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            $str .= '["banner/' . $file . '"],' . "\
";
        }
    }
    closedir($handle);
} 

$str = rtrim($str, ','); 

echo $str;

Spike was only giving you advice, not writing your code for you.

Can you see why it’s not outputting anything? There’s no echo:

$str = '';
if ($handle = opendir('banner')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            $str .= '["banner/' . $file . '"],' . "\
";
        }
    }
    closedir($handle);
} 

$str = rtrim($str, ','); 
echo $str;

Edit:

Beaten by speedy gonzales up there :rolleyes:

An alternative approach that avoids the need to strip the comma off the end after the loop finishes is to have the comma in front of the entry instead of behind. Then you can make the first entry a special case where you don’t add the comma on the front.

Knowing that it is the first time around a while loop is much easier to determine than knowing it is the last time around.

Hi everyone, I got it working. I used the substr function to remove the last two characters. I tried removing the last character, but it didn’t work.

Thank everyone for all of your help and input!



$str = '';
if ($handle = opendir('banner')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            $str .= '["banner/' . $file . '"],' . "\
";
        }
    }
    closedir($handle);
} 

$str = substr($str, 0, -2); 
echo $str;



Removing just the last character would remove the linefeed on the end but not the comma that precedes it. The comma is the second last character of each entry you are adding since you also add a linefeed after each.

So I know I’m unnecessarily keeping this solved thread going, but I feel like this is something we all run into pretty frequently and no standard has developed.

Deciding whether or not to output the comma is difficult in “while” loops, and much easier in “for” loops. However, I think iterating over an if statement that’s unnecessary all but one time isn’t exactly the best.

At one point I was hooked on building each element into an array and then running php’s implode() function. While this looked fancy, I imagine implode() is iterating over the array, so it’s probably not the best option.

rtrim($str,‘,’) is great, but I still don’t think it’s better than substr($str,0,-1). Any more opinions on this?

e39m5

Not if you do it the way I suggested earlier in the thread.

The way to avoid the difficulties is to add the comma in front of all entries except the first instead of after all entries except the last.

Determining the first entry in a while loop to not add the comma in front is easy.

$str = '';
if ($handle = opendir('banner')) {
    while (false !== ($file = readdir($handle))) {
        if ($file != "." && $file != "..") {
            $str .= $str?",\
":'';
            $str .= '["banner/' . $file . '"]';
        }
    }
    closedir($handle);
}
echo $str; 

It works better if you can move that first entry outside the loop so as to not need to repeat the test every time through though.

opendir and friends are old school and too verbose. Consider glob() instead


$list = array();
foreach(glob("banner/*") as $path)
	$list[] = sprintf('["banner/%s"]', basename($path));
$list = implode(', ', $list);

in php5.3 this can be even neater


$list = implode(', ', array_map(
	function($path) { return sprintf('["banner/%s"]', basename($path)); },
	glob("banner/*")
)); 

@e39m5: array + implode are better than string concatenations, because it involves less memory (de)allocations.

Off Topic:

welcome back Stereofrog!!