【问题标题】:PHP: Creating big HTML-table efficientlyPHP:有效地创建大 HTML 表
【发布时间】:2012-07-01 14:30:26
【问题描述】:

我正在根据我的 MySQL 数据库中的某些信息制作一个 HTML 表。我需要从数据库中获取的表包含行(rowidrowname)、列(columnidcolumnname) 和单元格数据。一个表格,将行和列中的 ID 链接在一起(cellidrowidcolumnidsomedata)。 该表如下所示:

__________| column1  | column2  | column3  | ...
     row1 | somedata | somedata |          |
----------|----------|----------|----------|-----
     row2 | somedata |          | somedata |
----------|----------|----------|----------|-----
...       |          |          |          |

我的方法是使用几个嵌套的 foreach 循环,如下所示:

$rows = new Rows();        //These objects are containers for objects
$columns = new Columns();  //that hold some of the database data. 
$alldata = new Alldata();  //MySQL queries within these objects are irrelevant, I think. They already get the relevant data

$count = count($alldata);

echo "<table>";
echo "<tr>";
echo "<td>&nbsp;</td>";

foreach ($columns->getColumns() as $column) {
    echo "<td>".$column->getColumnname()."</td>";
}

echo "</tr>";

foreach ($rows->getRows() as $row) {
    echo "<tr>";
    echo "<td>".$row->getRowname()."</td>";

    foreach ($columns->getColumns() as $column) {
        $last = 1;

        foreach ($alldata->getAlldata() as $data) {
            if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) { //If the column has data the related to the row
                echo "<td>".$data->getSomedata()."</td>";
                break;
            }
            if ($last == $count) { //if loop couldn't find any entries, it prints an empty cell
                echo "<td>&nbsp;<td>";
            }
            $last++
        }
    }
    echo "</tr>";
}
echo "</table>";

暴力破解,当数据库中的任何一张表都有几百行数据时,显然这不是很有效的方法,我不喜欢这样。 任何想法如何提高效率?有没有更好的方法来创建我需要的表格?

编辑:
这个问题思考了一周,终于给了我一些答案。就是这么简单!
我对我的 Column 对象类做了一些修改。以前,我的代码遍历了数据库中 celldata 表上所有可能的条目。现在 Column 对象得到一个 celldata 数组,其中 columnid's 匹配,我可以只使用该数据进行比较。

$rows = new Rows();
$columns = new Columns();

echo "<table>";
echo "<tr>";
echo "<td>&nbsp;</td>";

foreach ($columns->getColumns() as $column) {
    echo "<td>".$column->getColumnname()."</td>";
}

echo "</tr>";

foreach ($rows->getRows() as $row) {
    echo "<tr>";
    echo "<td>".$row->getRowname()."</td>";

    foreach ($columns->getColumns() as $column) {
        $last = 1;
        $count = count($column->getAlldata());

        foreach ($column->getAlldata() as $data) {
            if ($data->getCID() == $column->getID() & $data->getRID() == $row->getID()) {
                echo "<td>".$data->getSomedata()."</td>";
                break;
            }
            if ($last == $count) {
                echo "<td>&nbsp;<td>";
            }
            $last++
        }
    }
    echo "</tr>";
}
echo "</table>";

速度更快,虽然仍然是暴力破解,但需要处理的数据量更少。当然,现在的问题是 Column 对象可能会执行相当多的 MySQL 查询,具体取决于有多少 Columns

【问题讨论】:

  • 行和列ID是否保证按数字顺序排列?
  • @eggyal 行和列按名称排序,所以没有。

标签: php mysql object foreach html-table


【解决方案1】:

如果您通过连接表并在查询中指定 ORDER BY 子句来确保从 MySQL 提取的数据在 $alldata 中正确排序:

SELECT   data.*
FROM     data RIGHT JOIN rows USING (rowid) RIGHT JOIN columns USING (columnid)
ORDER BY rowname, columnname;

那么你只需要按顺序输出每个单元格:

echo '<table>';

echo '<thead>'
echo '<tr>';
echo '<th>&nbsp;</th>';
foreach ($columns->getColumns() as $column) {
    echo '<th scope="col">', htmlentities($column->getColumnname()), '</th>';
}
echo '</tr>';
echo '</thead>';

echo '<tbody>';
$data = $alldata->getAlldata();
foreach ($rows->getRows() as $row) {
    echo '<tr>';

    echo '<th scope="row">', htmlentities($row->getRowname()), '</th>';
    foreach ($columns->getColumns() as $column) {
        $d = each($data);
        echo '<td>', ($d ? htmlentities($d[1]->getSomedata()) : '&nbsp;'), '</td>';
    }

    echo '</tr>';
}
echo '</tbody>';

echo '</table>';

【讨论】:

  • 谢谢,我会试试看会发生什么。
  • 如果表真的很大,并且您想尝试一些微优化,您可以尝试使用逗号“,”而不是连接“。”在你的回声语句中。
  • 那个 MySQL 查询似乎做得很好。当我检查了一些对象的内容时,有些对象具有空值。也许这就是我一直在寻找的东西。但是,您的代码不适用于我的代码。问题在于 $d = $data->getSomedata()。 $data 不是一个对象而是一个数组,所以它不能使用那个函数。
  • @eggyal:是吗?函数 getAlldata() 获取对象数组,我的第三个 foreach 循环 (foreach ($alldata-&gt;getAlldata() as $data)) 遍历该数组中的对象。数组中的对象代表数据库中的行。
  • 是的。正如我所说,$alldata-&gt;getAlldata() 得到一个对象数组。我不能在那个数组上使用getSomedata() 函数。我必须先把它拆开才能使用getSomedata() 函数。为了清楚起见,AlldataData 是独立的对象,它们不共享任何功能。
【解决方案2】:

解决此问题的最佳方法是重写$alldata 的查询,使其按照您想要的顺序,就像eggyal 建议的那样。如果由于某种原因你不能这样做,你可以在开始时遍历$alldata 并从中创建一个正确索引的数组。像这样的:

$ordereddata = array();
foreach($alldata as $d) {
    $ordereddata[$d->getCID()][$d->getRID()] = $d->getSomedata();
}

现在您可以将 foreach($alldata) 循环替换为:

if(isset($ordereddata[$column->getID()][$row->getID()])) {
    echo "<td>{$ordereddata[$column->getID()][$row->getID()]}</td>";
} else {
    echo "<td>&nbsp;</td>";
}

【讨论】:

  • 我可以完全访问代码的任何部分。我实际上之前尝试过类似的东西,但没有奏效。我得到了所有数据,但我无法打印空单元格。每个单元格都向左对齐,它们之间没有空格。
猜你喜欢
  • 2019-09-22
  • 1970-01-01
  • 1970-01-01
  • 2014-07-17
  • 2018-04-16
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
相关资源
最近更新 更多