提问人:Thomas Owens 提问时间:11/5/2008 最后编辑:Brian Tompsett - 汤莱恩Thomas Owens 更新时间:9/14/2016 访问量:1287
循环是构建表的最佳方式吗?
Are loops the best way to build a table?
问:
我必须构建一个 HTML 表格,显示用户与访问页面的数据。使用 for 和/或 foreach 循环似乎很笨拙,但我想不出更好的方法。我正在使用 PHP,但我认为这是与语言无关的。
答:
好吧,如果您有多行,并且每行的数据格式相似,我想不出一种方法来创建一个避免使用循环的表。这种东西基本上就是循环的发明目的。
如果您向我们提供有关要构建的表的更多详细信息,也许我们可以制定更好的方法。
如果你不使用某种循环,那么你需要对代码中的行数和列数进行硬编码,这可能是一个更糟糕的想法
如果表中的数据是动态的,则必须使用循环。即使你得到了一个为你生成表的组件,它在内部也会使用一个循环。
这取决于你对“最好”的定义。FOR 循环可以很好地完成这项工作。我不是PHP程序员,但是在.NET中,您可以使用Repeater,这是一种可用于声明表HTML的模板。它有页眉、页脚和每个项目的模板。将数据源绑定到转发器,它将比使用 FOR 循环更优雅地为您生成表 HTML。我想PHP中可能有某种模板等价物。
不过,最后,即使是中继器也使用了某种循环......
避免循环可能是不可能的,如果不在实现中,那么它仍然会发生在机器级别。
但是,如果你想在没有讨厌的代码的情况下保持“纯粹”,你至少可以做到:
$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 )) );
但要注意,这很难读懂,你坚持下去,总有一天你会在口齿不清中醒来。
评论
我强烈推荐 PHP 的 Smarty 模板引擎。这将允许您使用 Smarty 语法将表(以及相关的循环,这是不可避免的)移动到模板中,因此它将更清晰,与您的业务逻辑更加分离。您将能够将示例中的几乎所有代码替换为 HTML 代码段中的一些简单标记。查看 Smarty 页面上的速成课程,了解使用表格的示例。
我通常使用循环,为此,在 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;
}
为什么要避免循环?如果您有一组项目,并且想要显示每个项目,那么循环使用该集合肯定是显而易见的解决方案吗?
如果您尝试将模型与视图分离,或者编写更具可读性的代码,那么很好;但循环本身并不是坏事。
评论