在两列表中连续显示php嵌套数组结果

时间:2012-01-16 17:51:40

标签: php arrays nested html-table

我有一个嵌套数组,其他三个数组:$ online,$ busy和$ offline,以便按照这个顺序显示结果。

$conteudo = array($online, $ocupado, $offline);

所需的结果将是两列中的表格,以连续流程显示结果,如下所示:

online1 | online2
online3 | busy1
busy2   | offline1
offline2| offline3
offline4|

我一直在尝试很多foreach循环并且在改变html标签,但是我能得到的最接近的结果是:

<table width='100%' cellpadding='5' border="1">
<?php
$i = 1; //contador de colunas
$max_colunas = 2; // numero de colunas
foreach ($conteudo as $row) {
    echo "<tr>";
    foreach ($row as $col) {
        foreach ($col as $cell) {
            if ($i == 1) {
                echo "<td>" . $cell . "</td>";
            } elseif ($i == $max_colunas){
                echo "<td>" . $cell . "</td></tr>";
                $i = 0;
            } else {
                echo "<td>" . $cell . "</td>";
            }
            $i++;
        }
    }   
    echo "</tr>"; 
}   

此代码将输出如下表格:

 onine1  | online2 |online3
 busy1   | busy2   |
 offline1|offline2 |offline3|offline4

我无法找出为什么它完全忽略$max_colunas,似乎它会在行中打印出数组内的所有元素。

如果我删除行:

 echo "<tr>";
 echo "</tr>";

foreach的开头和结尾,它将像这样输出所有行:

onine1  | online2 |online3 | busy1 | busy2 |offline1|offline2 |offline3|offline4

任何有关获得所需输出格式的建议都将受到赞赏。


于17/01编辑:

这就是我从以下方式获取数组的方法:

//group people
$online = array(); //group online
$ocupado = array(); //group ocupado
$offline = array(); //group offline

//select people to group
$atendentes = mysql_query("SELECT nome FROM atendentes ORDER BY nome") or die(mysql_error());
$atendentedb = array();

//put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
    $atendentedb[] = array('nome' => $row["nome"], 'online' => false);
}


//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();

foreach ($names as $name):
    //foreach ($atendentedb as $atendente):
    for($i = 0; $i < count($atendentedb); $i++):
        $att = strtolower($name->username);

        if ($atendentedb[$i]['nome'] == $att):          
            $atendentedb[$i]['online'] = true;
            break;
        endif;

   endfor;
endforeach;

//check each selected people
foreach ($atendentedb as $atendente) :
    //save temporary data
    $online_ = $atendente['online'];
    $nome_   = $atendente['nome'];  

    //if selected people online
    if ($online_) :
        //take status to show
        $status = mysql_query("SELECT status FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
        while ($row = mysql_fetch_assoc($status)):
            $statusdb = $row["status"];
        endwhile;

        //verify and save deppending on status
        switch ($statusdb):

            //if online
            case "disponivel":
                $descricao = mysql_query("SELECT hp_online FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
                while ($row = mysql_fetch_assoc($descricao)):
                $online[] = array('info'=>$row['hp_online']);
                endwhile;
                break;

        //if busy
            case "ocupado":
                $descricao = mysql_query("SELECT hp_busy FROM atendentes WHERE nome = '$nome_'  LIMIT 1") or die(mysql_error());
                while ($row = mysql_fetch_assoc($descricao)):
                    $ocupado[] = array('info'=>$row['hp_busy']);
                endwhile;
                break;
        endswitch;

    //if offline
    else:
        $descricao = mysql_query("SELECT hp_offline, horario FROM atendentes WHERE nome = '$nome_' LIMIT 1") or die(mysql_error());
        while ($row = mysql_fetch_assoc($descricao)):
           $offline[] = array('info'=>$row['hp_offline'], 'horario'=>$row['horario']);
        endwhile;

    endif;
endforeach;

EDITED

因此,在遵循DaveRandom的帮助说明之后,我得到了这段代码,除了来自数组$offline的结果的“神秘”行为外,它实际上远离正确的格式,显示全部“阻止”(一行中的所有单元格,或列中的所有单元格),而其他数组显示完美(??)。

   //group people
   $online = $ocupado = $offline = array();

   //select people to group
   $query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
      FROM atendentes
      ORDER BY nome";
  $atendentes = mysql_query($query) or die(mysql_error());
  $atendentedb = array();

  // put selected people in array
  while ($row = mysql_fetch_assoc($atendentes)) {
  $atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
  }

  //take people online now and check in selected people
  $names = modWhosonlineCustom::getOnlineUserNames();
  foreach ($names as $name) {
  $uname = strtolower($name->username);
  if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
  }

  //check each selected people
  foreach ($atendentedb as $name => $atendente) {

  //if selected people online
  if ($atendente['online']) {

 //verify and save deppending on status
 switch ($atendente['status']) {

  //if online
  case 'disponivel':
    $atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
    break;

  //if busy
  case 'ocupado':
    $atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
    break;

  }

  //if offline
  } else {

  $atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'];
$atendentedb[$name]['info'] = $offline[] = $atendente['horario'];

  }

}

  //*******Display Results
  $conteudo = array_merge($online, $ocupado, $offline);
  $max_colunas = 2; // numero de colunas

  // Start the table
  echo '<table width="100%" cellpadding="5" border="1">'."\n";

  // Loop all the objects
  for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
  if ($j == 0) {
  // Output the beginning of a row
  echo "  <tr>\n";
  }
  // Always output a data cell
  echo "    <td>$conteudo[$i]</td>\n";
  if (++$j >= $max_colunas) {
  // Output the end of a row and reset the cell counter
  echo "  </tr>\n";
  $j = 0;
  }
  }

  if ($j) {
  // We may end up with an incomplete row at the end, so pad it with empty cells
  // and close the row
  while ($j++ < $max_colunas) {
 echo "    <td></td>\n";
 }
 echo "  </tr>\n";
 }

 // Close the table
 echo "</table>";

2 个答案:

答案 0 :(得分:0)

我要说的是,这里要做的第一件事是“扁平化”阵列 - 具有多个尺寸使得它比它需要的复杂得多。因此,而不是像这样创建$conteudo

$conteudo = array($online, $ocupado, $offline);

......改为:

$conteudo = array_merge($online, $ocupado, $offline);

然后你可以这样做:

$max_colunas = 2; // numero de colunas

// Start the table
echo '<table width="100%" cellpadding="5" border="1">'."\n";

// Loop all the objects
for ($i = 0, $j = 0; isset($conteudo[$i]); $i++) {
  if ($j == 0) {
    // Output the beginning of a row
    echo "  <tr>\n";
  }
  // Always output a data cell
  echo "    <td>$conteudo[$i]</td>\n";
  if (++$j >= $max_colunas) {
    // Output the end of a row and reset the cell counter
    echo "  </tr>\n";
    $j = 0;
  }
}

if ($j) {
  // We may end up with an incomplete row at the end, so pad it with empty cells
  // and close the row
  while ($j++ < $max_colunas) {
    echo "    <td></td>\n";
  }
  echo "  </tr>\n";
}

// Close the table
echo "</table>";

See it working

修改

尝试使用此代码生成阵列。请注意,输出数组的结构已经更改为适合我上面的代码示例 - 如果您在脚本中的任何其他位置使用此数据,则还需要修改该代码。我已经修改了这个,所以只有一个数据库查询,这似乎只是所需要的。我还修改了它,以便$atendentedb保存所有用户数据,包括statusinfo键,所有行都包含horario键。

由于您的输入数组最初包含的数据多于此代码创建的数据,因此代码可能需要进一步修改 - 但请试一试,看看您是如何继续的。

//group people
$online = $ocupado = $offline = array();

//select people to group
$query = "SELECT nome, status, hp_online, hp_busy, hp_offline, horario
          FROM atendentes
          ORDER BY nome";
$atendentes = mysql_query($query) or die(mysql_error());
$atendentedb = array();

// put selected people in array
while ($row = mysql_fetch_assoc($atendentes)) {
  $atendentedb[strtolower($row['nome'])] = array_merge($row, array('online' => FALSE));
}

//take people online now and check in selected people
$names = modWhosonlineCustom::getOnlineUserNames();
foreach ($names as $name) {
  $uname = strtolower($name->username);
  if (isset($atendentedb[$uname])) $atendentedb[$uname]['online'] = TRUE;
}

//check each selected people
foreach ($atendentedb as $name => $atendente) {

  //if selected people online
  if ($atendente['online']) {

    //verify and save deppending on status
    switch ($atendente['status']) {

      //if online
      case 'disponivel':
        $atendentedb[$name]['info'] = $online[] = $atendente['hp_online'];
        break;

      //if busy
      case 'ocupado':
        $atendentedb[$name]['info'] = $ocupado[] = $atendente['hp_busy'];
        break;

    }

  //if offline
  } else {

    $atendentedb[$name]['info'] = $offline[] = $atendente['hp_offline'].' '.$atendente['horario'];

  }

}

答案 1 :(得分:0)

我认为你应该在里面更新计数器 foreach ($col as $cell) { }所以它将计算内部数组的元素,并在那里移动<tr>的decalration。 if (!is_int($i/2)) { print '<tr><td>' }