2012-03-08 5 views
1

Я пытаюсь распространить результаты цикла foreach() на два столбца таблицы (извините, не могу опубликовать изображения, так как это мой первый пост для переполнения стека). Я вижу, где я ошибаюсь, но не знаю, как исправить это. Я, может быть, next() вместо того, чтобы повторять foreach(), но, похоже, не может работать так. Любая помощь будет принята с благодарностью.Распространение 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> 

ответ

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

Но что произойдет, если вы вызовете следующий() по последнему пункту?

Эта функция может возвращать как логическое значение FALSE, но может также возвращать не-логическое значение, которое приводится к FALSE. Пожалуйста, прочитайте раздел о Булевы для получения дополнительной информации. Используйте оператор === для проверки возвращаемого значения этой функции.

Вы должны разорвать цикл, если следующая возвращает ложное, например,:

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

РНР руководство для следующего также включает в себя важное замечание:

Примечание: Вы не сможете отличить конец массива из логическое значение FALSE элемента. Для правильного прохождения массива, который может содержать FALSE, см. Функцию each().

+0

Теперь это то, что я называю тщательным ответом с помощью встроенного урока. Спасибо @jpic, что вы звезда. И дело касается упрощения кода. –

+0

В любое время, пожалуйста [закройте свой вопрос] (http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – jpic

+0

Хороший ответ. Обратите внимание, что окончательное решение создаст таблицу, в которой последняя строка содержит только один td и не закрывающий тэг. Должен повторять пустой td и закрывать tr перед разрывом, если ложная часть. – eselk

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> 

It не будет правильно обрабатывать пустой массив, поэтому вы должны добавить свой собственный код для его обработки. Вы можете изменить columnCount на все, что захотите, если вам нужно больше двух столбцов.

Смежные вопросы