将foreach()结果传播到表的两列

时间:2012-03-08 08:33:48

标签: php foreach html-table

我正在尝试将foreach()循环的结果传播到表的两列(抱歉无法发布图像,因为这是我的第一篇文章到堆栈溢出)。我可以看到我出错的地方,但不知道如何纠正它。我虽然可能是next()而不是重复foreach()但似乎无法让它发挥作用。任何帮助将不胜感激。

我需要这个:
result1 result2
result3 result4

但我得到了这个:
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>

2 个答案:

答案 0 :(得分:5)

您应该尝试在调试时简化代码。这有助于您隔离问题并使其更容易,以便像StaceOverflow 这样的社区帮助您。它看起来像这样:

<?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>

你会看到这个(错误的)输出,这几乎就是你所说的问题不是吗? ;)

string(3) "foo"
string(3) "foo"
string(3) "bar"
string(3) "bar"
string(4) "lolo"
string(4) "lolo"

next()的签名是:

mixed next ( array &$array )

这意味着它从一个通过引用传递的数组中返回任何类型的值。在你的情况下,它适用于:

$tag = next( $tags );

但是如果你在最后一个项目上调用next()会发生什么?

  

此函数可能返回布尔值FALSE,但也可能返回a   非布尔值,其值为FALSE。请阅读有关的部分   布尔值获取更多信息。使用===运算符进行测试   返回此函数的值。

如果下一个返回false ,你应该打破for循环,例如:

$tag = next( $tags );
if ( $tag === false ) break;

更详细的例子:

<?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>

输出就好了

object(Tag)#1 (1) {
  ["tag"]=>
  string(3) "foo"
}
object(Tag)#3 (1) {
  ["tag"]=>
  string(4) "lolo"
}
object(Tag)#2 (1) {
  ["tag"]=>
  string(3) "bar"
}

以下是应用于您的代码的解决方案(已测试/正在工作):

<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>

下一页的php手册还包含重要提示

  

注意:您将无法区分数组的结尾与   boolean FALSE元素。正确遍历可能包含的数组   FALSE元素,请参阅each()函数。

答案 1 :(得分:0)

如果两列完全相同,或者特别是如果你需要超过2列,我推荐这种浓缩方法(我没有对此进行过很多测试):

            <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>&nbsp;</td>";
            }
            ?>
                </tr>
            </table>

不会正确处理空数组,因此您应该添加自己的代码来处理它。如果您想要多于2列,可以将columnCount更改为您想要的任何内容。