当输出到<table>
格式时如何显示您的MySQL结果?我觉得我自己的代码需要一些修改。我这样做对吗?
编辑:我的代码显然是错误的/丑陋的。在只使用普通PHP而不使用Smarty的情况下,最好的方法是什么?
$items_per_row = 3; // How many <td> I want to add for every <tr>
// Query the MySQL db
$sthandler = $dbhandler->prepare("SELECT col1, col2 FROM sampletable");
$sthandler->execute();
// Save each row to array
$allitems = array();
while($row = $sthandler->fetch(PDO::FETCH_ASSOC)){
$allitems[] = $row;
}
$markup = '';
foreach($allitems as $key=>$val){
$col1 = $allitems[$key]['col1'];
$col2 = $allitems[$key]['col2'];
// START THE MARKUP HERE
$markup .= $key % $items_per_row == 0 ? '<tr>' : '';
$markup .= <<<EOD
<td>
<p>$col1</p>
<p>$col2</p>
</td>
EOD;
$markup .= ($key + 1) % $items_per_row == 0 ? '</tr>' : '';
}
我可以直接写<table><?php echo $markup; ?></table>
将业务逻辑与表示代码分开!!
我使用模板解析器,将HTML与PHP分开。例如,在Smarty中,我会使用如下命令:
// Sample data
$tableData = array(
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
);
// Create the view
$tpl = new Smarty();
$tpl -> assign('table', $tableData);
$tpl -> display('myPage.tpl');
然后在模板文件中构建表:
<table>
{foreach from=$table item=row}
<tr>
<td>{$row.0|escape}</td>
<td>{$row.1|escape}</td>
</tr>
{/foreach}
</table>
这将你的HTML与你的PHP代码分开,使它更容易添加新功能,并使你的代码更具可读性。
编辑
你真的有必要把问题改那么多吗?
很好,用这个模板代替:
<table>
<?php foreach ($tableData as $row) { ?>
<tr>
<td><?php echo htmlspecialchars($row[0]); ?></td>
<td><?php echo htmlspecialchars($row[1]); ?></td>
</tr>
<?php } ?>
</table>
用法:
// Sample data
$tableData = array(
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
);
// Create the view
include('myPage.php');
当然,这个解决方案比使用一个合适的模板引擎更脏。
这是在HTML模板中显示数组的基本函数。
您可以通过添加可选参数来改进它,允许控制htmlspecialchars()
是否应该应用于值,为偶数/奇数行添加一些样式,告诉echo
或return
HTML结果等。
function formatToTable($array)
{
$str = "<table>'n";
foreach($array as $row)
{
$str .= "<tr>'n";
foreach($row as $value)
$str .= "<td>".htmlspecialchars($value)."</td>'n";
$str .= "</tr>'n";
}
$str .= "</table>'n";
echo $str;
}
你可以像Tom建议的那样,使用像Smarty这样的模板引擎(当然也有利弊)。在这种情况下,你可以注册formatToTable()
作为一个新的Smarty函数:
$smarty->register_function('formatToTable', 'formatToTable');
// and then into templates simply do:
{formatToTable array=$array}
// note that the formatToTable() function has to be slightly modified:
function formatToTable($params)
{
if (!isset($params['array']) || !is_array($params['array']))
throw new Exception("Missing parameter 'array'"); // for example
$str = "<table>'n";
// etc.
}
您的代码可以稍微简化一点,对吧,但这很正常。已经有了一些提示,可以更容易地从数据库中获取数据:
// Query the MySQL db
$sthandler = $dbhandler->prepare("SELECT col1, col2 FROM sampletable");
$sthandler->execute();
$allitems = $sthandler->fetchAll(PDO::FETCH_ASSOC);
然后你想把col1
和col2
都放在它自己的段落中。这已经是每一个sql结果行,所以这是好的。
那么您希望在输出的每个表行中有三个这样的对。PHP中有这样一个函数:
array_chunk($allitems, $items_per_row, 1);
这将生成您正在查找的表行。因为它可能是空的,但仍然代表一个表,所以我再次将它包装到一个额外的数组中:
### PROCESS DATA (here obviously for viewing)
$allitems = array(array_chunk($allitems, $items_per_row, 1));
因此,现在数据处于输出的正确结构中。但是对于这个数据的表示,每个元素需要在它周围得到一个HTML标记——递归地。从外部到内部的标签是:
### RENDERER
$tags = array('table', 'tr', 'td', 'p');
剩下的是一个装饰函数,用于在每个成员周围添加这些标签:
$decorate = function($array, $tags, $f) {
$tag = array_shift($tags);
foreach($array as $element)
echo "<$tag>",
is_array($element)
? $f($element, $tags, $f)
: htmlspecialchars($element),
"</$tag>";
};
它将标签递归地包装到数组的适当级别,这意味着如果里面有更多的项,函数将调用另一个函数(参见is_array
测试)。
现在一切都准备好了,数组被标记装饰,数组的内部元素将使用相同的函数,所以它也作为参数传递:
$decorate($allitems, $tags, $decorate);
。演示。示例代码一览:
<?php
### CONFIGURATION
$items_per_row = 3; // How many <td> I want to add for every <tr>
### GET DATA FROM STORE
IF (0):
// Query the MySQL db
$sthandler = $dbhandler->prepare("SELECT col1, col2 FROM sampletable");
$sthandler->execute();
$allitems = $sthandler->fetchAll(PDO::FETCH_ASSOC);
ELSE:
// Static test data
$allitems = array(
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
array('col1', 'col2'),
);
ENDIF;
### PROCESS DATA (here obviously for viewing)
$allitems = array(array_chunk($allitems, $items_per_row, 1));
### RENDERER
$tags = array('table', 'tr', 'td', 'p');
$decorate = function($array, $tags, $f) {
$tag = array_shift($tags);
foreach($array as $element)
echo "<$tag>",
is_array($element)
? $f($element, $tags, $f)
: htmlspecialchars($element),
"</$tag>";
};
$decorate($allitems, $tags, $decorate);