循环是构建表的最佳方式吗?

Are loops the best way to build a table?

提问人:Thomas Owens 提问时间:11/5/2008 最后编辑:Brian Tompsett - 汤莱恩Thomas Owens 更新时间:9/14/2016 访问量:1287

问:

我必须构建一个 HTML 表格,显示用户与访问页面的数据。使用 for 和/或 foreach 循环似乎很笨拙,但我想不出更好的方法。我正在使用 PHP,但我认为这是与语言无关的。

php 循环 html-table

评论


答:

4赞 James Curran 11/5/2008 #1

好吧,如果您有多行,并且每行的数据格式相似,我想不出一种方法来创建一个避免使用循环的表。这种东西基本上就是循环的发明目的。

如果您向我们提供有关要构建的表的更多详细信息,也许我们可以制定更好的方法。

3赞 Gareth 11/5/2008 #2

如果你不使用某种循环,那么你需要对代码中的行数和列数进行硬编码,这可能是一个更糟糕的想法

2赞 Vincent Ramdhanie 11/5/2008 #3

如果表中的数据是动态的,则必须使用循环。即使你得到了一个为你生成表的组件,它在内部也会使用一个循环。

1赞 Maxam 11/5/2008 #4

这取决于你对“最好”的定义。FOR 循环可以很好地完成这项工作。我不是PHP程序员,但是在.NET中,您可以使用Repeater,这是一种可用于声明表HTML的模板。它有页眉、页脚和每个项目的模板。将数据源绑定到转发器,它将比使用 FOR 循环更优雅地为您生成表 HTML。我想PHP中可能有某种模板等价物。

不过,最后,即使是中继器也使用了某种循环......

4赞 Kent Fredric 11/5/2008 #5

避免循环可能是不可能的,如果不在实现中,那么它仍然会发生在机器级别。

但是,如果你想在没有讨厌的代码的情况下保持“纯粹”,你至少可以做到:

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

至少这样,它可能在某种程度上是可维护的。而且您不必担心字符串不完整。

您还可以将其中一些代码替换为

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

虽然相当简洁,但最终可能会让你陷入困境,需要重新编码。(并且 implode 在内部运行一个循环,所以这是一个双输 )。

如果您不介意额外的函数调用(并且仍在运行的循环)的开销,这可能会使代码更简洁,而不会有太多的负面影响:

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

但要注意,这很难读懂,你坚持下去,总有一天你会在口齿不清中醒来。

评论

0赞 Thomas Owens 11/5/2008
我真的很喜欢。它使代码比带有随机字符串的循环更整洁。
0赞 Javier 11/5/2008
在PHP代码中破坏HTML,这(IMNSHO)甚至比在HTML中破坏代码更糟糕。
0赞 troelskn 11/5/2008
在 HTML 中嵌入数据时,请记住使用 htmlspecialchars 对数据进行转义
0赞 troelskn 11/5/2008
最后的函数式示例将不起作用 - PHP 没有词法范围。
0赞 Colonel Sponsz 11/5/2008
这样做会让情况变得更糟!;-)
2赞 rmeador 11/5/2008 #6

我强烈推荐 PHP 的 Smarty 模板引擎。这将允许您使用 Smarty 语法将表(以及相关的循环,这是不可避免的)移动到模板中,因此它将更清晰,与您的业务逻辑更加分离。您将能够将示例中的几乎所有代码替换为 HTML 代码段中的一些简单标记。查看 Smarty 页面上的速成课程,了解使用表格的示例。

-1赞 troelskn 11/6/2008 #7

我通常使用循环,为此,在 PHP 中。在支持函数式编程的语言中,我会以不同的方式做。implode

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;
}
0赞 Hugh Bothwell 11/6/2008 #8

为什么要避免循环?如果您有一组项目,并且想要显示每个项目,那么循环使用该集合肯定是显而易见的解决方案吗?

如果您尝试将模型与视图分离,或者编写更具可读性的代码,那么很好;但循环本身并不是坏事。

评论

0赞 Thomas Owens 11/6/2008
不,它们还不错。但是,当你有一个庞大的数据集,并且正在用它做一些奇怪的事情时,循环无助于使代码可读。