Reputation: 11
I'm trying to spread the results of a foreach()
loop over two columns of a table (sorry can't post images as this is my first post to stack overflow). I can see where I'm going wrong but haven't a clue how to correct it. I though maybe a next()
instead of repeating the foreach()
but can't seem to get that to work. Any help would be greatly appreciated.
I need this:
result1 result2
result3 result4
but I'm getting this:
result1 result1
result2 result2
<table>
<?php
foreach ($tags as $tag) {
echo '<tr><td><input name="taga[]" type="checkbox" value="'.$tag->tag.'" id="'.str_replace(" ", "_", $tag->tag).'_id"';
foreach ($search as $searchword) {
if ($searchword == $tag->tag) echo 'checked="checked"';
}
echo ' /><label for="'.str_replace(" ", "_", $tag->tag).'_id">'.$tag->tag.'</label></td>';
next ($tag);
echo '<td><input name="taga[]" type="checkbox" value="'.$tag->tag.'" id="'.str_replace(" ", "_", $tag->tag).'_id"';
foreach ($search as $searchword) {
if ($searchword == $tag->tag) echo 'checked="checked"';
}
echo ' /><label for="'.str_replace(" ", "_", $tag- >tag).'_id">'.$tag->tag.'</label></td></tr>';
}
?>
</table>
Upvotes: 1
Views: 2024
Reputation: 6884
If both columns are exactly the same, or especially if you need more than 2, I recommend this condensed approach (I haven't done a lot of testing on this):
<table>
<tr>
<?php
$count = 0;
$columnCount = 2;
foreach ($interests as $interest) {
if($count++ % $columnCount == 0){
echo "</tr><tr>";
}
echo "<td>$interest->name</td>";
}
while($count++ % $columnCount != 0){
echo "<td> </td>";
}
?>
</tr>
</table>
It will not handle an empty array correctly, so you should add your own code to handle that. You can change columnCount to whatever you want, if you want more than 2 columns.
Upvotes: 0
Reputation: 33420
You should try to simplify your code when debugging. This would help you isolate the problem and make it easier for communities like StaceOverflow to help you. It looks like this:
<?php
// some fixtures for us to work with
$tags = array('foo', 'bar', 'lolo', );
?>
<pre>
<?php
// your actual issue
foreach ($tags as $tag) {
var_dump( $tag );
next( $tag );
var_dump( $tag );
}
?>
</pre>
You'd see this (wrong) output, which is pretty much the problem you're talking about isn't it ? ;)
string(3) "foo"
string(3) "foo"
string(3) "bar"
string(3) "bar"
string(4) "lolo"
string(4) "lolo"
The signature of next() is:
mixed next ( array &$array )
Which means that it returns a value of any type from an array which is passed by reference. In your case it applies like this:
$tag = next( $tags );
But what happens if you call next() on the last item ?
This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE. Please read the section on Booleans for more information. Use the === operator for testing the return value of this function.
You should break the for loop if next returns false, e.g.:
$tag = next( $tags );
if ( $tag === false ) break;
More elaborated example:
<?php
class Tag {
public $tag;
public function __construct( $tag ) {
$this->tag = $tag;
}
}
$tags = array( );
foreach ( array('foo', 'bar', 'lolo', ) as $word) {
$tags[] = new Tag( $word );
}
$search = array( 'bar', 'the' );
?>
<pre>
<?php
foreach ($tags as $tag) {
var_dump( $tag );
$tag = next( $tags );
if ( $tag === false ) {
break;
}
var_dump( $tag );
}
?>
</pre>
Will output just fine:
object(Tag)#1 (1) {
["tag"]=>
string(3) "foo"
}
object(Tag)#3 (1) {
["tag"]=>
string(4) "lolo"
}
object(Tag)#2 (1) {
["tag"]=>
string(3) "bar"
}
Here's the solution applied to your code (tested/working):
<table>
<?php
foreach ($tags as $tag) {
echo '<tr><td><input name="taga[]" type="checkbox" value="'.$tag->tag.'" id="'.str_replace(" ", "_", $tag->tag).'_id"';
foreach ($search as $searchword) {
if ($searchword == $tag->tag) echo 'checked="checked"';
}
echo ' /><label for="'.str_replace(" ", "_", $tag->tag).'_id">'.$tag->tag.'</label></td>';
$tag = next ($tags);
if ( $tag === false ) {
break;
}
echo '<td><input name="taga[]" type="checkbox" value="'.$tag->tag.'" id="'.str_replace(" ", "_", $tag->tag).'_id"';
foreach ($search as $searchword) {
if ($searchword == $tag->tag) echo 'checked="checked"';
}
echo ' /><label for="'.str_replace(" ", "_", $tag->tag).'_id">'.$tag->tag.'</label></td></tr>';
}
?>
</table>
The php manual for next also includes an important note:
Note: You won't be able to distinguish the end of an array from a boolean FALSE element. To properly traverse an array which may contain FALSE elements, see the each() function.
Upvotes: 5