Pergunta

Eu tenho que construir uma tabela HTML que mostra os dados para os usuários contra páginas visitadas. Parece klunky usar para loops e / ou foreach, mas eu não consigo pensar em nada melhor. Eu estou usando PHP, mas eu diria que este é agnóstico linguagem.

Foi útil?

Solução

Evitar laços provavelmente não é possível, se não na implementação, em seguida, ele irá ainda acontecer a nível da máquina.

No entanto, se você quiser tentar estadia 'puro' sem código desagradável, você pode pelo menos fazer:

$tableformat = '<table><thead>%s</thead><tbody>%s</tbody></table>';
$rowformat   = '<tr>%s</tr>'; 
$cellformat  = '<td>%s</td>'; 

$hdata = '';
foreach( $data[0] as $cellname => $cellvalue )
{
   $hdata  .= sprintf( $cellformat, $cellname ); 
}
$hdata = sprintf( $rowformat, $hdata ); 
$rdata = "";
foreach( $data as $rownum => $rowvalue ) 
{ 
   $row = "";
   foreach( $rowvalue as $colname => $colvalue ) 
   {
       $row .= sprintf( $cellformat, $colvalue );  
   }
   $rdata .= sprintf($rowformat,$row); 
}
return sprintf( $tableformat, $hdata, $rdata ); 

Pelo menos dessa forma ele pode ser um pouco sustentável. e você não tem muita preocupação com cordas incompletos.

Você também pode subsitutue alguns dos que o código com

   $hdata = "<tr><td>" . implode( "</td><td>", array_keys( $data[0] )) . "</td></tr>";
   $rdata .= "<tr><td>" . implode( "</td><td>", $rowvalue ) . "</td></tr>"; 

Qual enquanto sendo bastante concisa, possivelmente irá levá-lo em um pouco de água quente e, eventualmente, ele vai precisar de recodificação. (E implode corre internamente um loop, por isso é um perde-perde).

Se você não se importa o cabeça sobre de chamadas de função extra (e loops ainda em execução) isso poderia tornar mais código conciso, sem muitas Negativos:

 $tableformat = '<table><thead>%s</thead><tbody>%s</tbody></table>';
 $rowformat   = '<tr>%s</tr>'; 
 $cellformat  = '<td>%s</td>'; 

function tr( $cells )
{  
   $o = "";
   foreach( $cells as $i => $v )
   {  
      $o .= sprintf( $cellformat, $v ); 
   }
   return sprintf( $rowformat, $o );  
}


return sprintf( $tableformat, 
               tr( array_keys($data[0])), 
               implode("", array_map( 'tr', $data )) ); 

Mas cuidado, isso é difícil de ler, e você manter isso um dia você vai acordar com lisp.

Outras dicas

Bem, se você tiver várias linhas, com dados formatados da mesma forma em cada linha, eu não consigo pensar em uma maneira de criar uma tabela que evita usar um loop. Esse tipo de coisa é basicamente o que laços foram inventados para.

Se você nos deu mais detalhes sobre a mesa que você quer construir, talvez possamos formular um método melhor.

Se você não usar alguns tipo de circuito, então você precisa codificar o número de linhas e colunas em seu código, que é provavelmente uma idéia muito pior

Se os dados na tabela é dinâmico, então você tem que usar um loop. Mesmo se você receber um componente que gera a tabela para você, internamente ele vai usar um loop.

Eu recomendo o Smarty motor de templates para PHP. Isto irá permitir que você mova sua mesa (e do loop associado, que é inevitável) para o modelo usando a sintaxe Smarty, por isso vai ser mais clara e separada da sua lógica de negócio. Você seria capaz de substituir quase todo o código no seu exemplo com algumas tags simples em um trecho de HTML. Confira o curso intensivo na página Smarty para um exemplo do uso de uma tabela.

Isso depende da sua definição de "melhor". PARA laços irá fazer o trabalho muito bem. Eu não sou um programador PHP, mas em .NET, você pode usar o Repeater, um tipo de modelo que você pode usar para declarar o HTML tabela. Tem modelos para o cabeçalho, rodapé e cada item. Você vincular uma fonte de dados para o repetidor, e ele irá gerar o HTML mesa para você um pouco mais elegante do que usando PARA loops. Eu imagino que pode haver algum tipo de templates equivalente em PHP.

No final, porém, até mesmo o Repeater usa algum tipo de laço ...

Por que você quer para evitar loops? Se você tem um conjunto de itens, e você deseja exibir cada item, certamente looping sobre o conjunto é a solução óbvia?

Se você está tentando separar o modelo a partir da visão, ou escrever o código mais legível, boa; mas laços não são inerentemente mau.

Eu costumo usar loops e implode para isso, em PHP. Em uma linguagem, que suporta programação funcional eu o faria de forma diferente.

function render_table($data) {
  $html = '<table>';
  $tr = array();
  foreach (array_keys($data[0]) as $key) {
    $tr[] = '<th>' . htmlspecialchars($key) . '</th>';
  }
  $html .= "\n" . '<thead>' . "\n" . '<tr>' . "\n" . implode("\n", $tr) . '</tr>' . '</thead>';
  $tbody = array();
  foreach ($data as $row) {
    $tr = array();
    foreach ($row as $value) {
      $tr[] = '<td>' . htmlspecialchars($value) . '</td>';
    }
    $tbody[] = '<tr>' . "\n" . implode("\n", $tr) . '</tr>';
  }
  $html .= "\n" . '<tbody>' . "\n" . implode("\n", $tbody) . '</tbody>';
  $html .= '</table>';
  return $html;
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top