【问题标题】:Fetch more data inside foreach在 foreach 中获取更多数据
【发布时间】:2025-12-09 13:30:01
【问题描述】:

所以我需要从我的数据库中获取数据,例如部分、项目名称和每个部分的小计,并获取所有项目的总计。 我偶然发现了下面的代码并将其修改为我的要求。 该代码运行良好,但我需要显示更多数据,如项目描述、数量、价格、状态等。 下面的代码可以正常工作并且没有任何问题,但我需要更多数据(描述、数量、价格等)来显示在我的表格中,但我不知道该怎么做。 我需要显示的数据也在 projectscostbreakdown_areaname、projectscostbreakdown_itemname 和 projectscostbreakdown_totalcost 所在的同一行。

<?php
$projectsid = $_GET['projectrfpid'];
$itemdeleted = 1;
$itemfirstothers = 'OTHERS';
$query = $conn->prepare('SELECT projectscostbreakdown_id,
projectscostbreakdown_projectid,
projectscostbreakdown_areaname,
projectscostbreakdown_itemname,
projectscostbreakdown_itemdescription,
projectscostbreakdown_qty,
projectscostbreakdown_costpiece,
projectscostbreakdown_budgeted,
projectscostbreakdown_totalcost,
projectscostbreakdown_note,
projectscostbreakdown_addedby,
projectscostbreakdown_addeddate,
projectscostbreakdown_deleted,
projectscostbreakdown_lastedit,
projectscostbreakdown_lasteditby
FROM projectscostbreakdown WHERE projectscostbreakdown_projectid=:projectsid && projectscostbreakdown_deleted=:itemdeleted ORDER BY projectscostbreakdown_areaname=:itemfirstothers, projectscostbreakdown_areaname ASC, projectscostbreakdown_id DESC');
$query->bindParam(':projectsid', $projectsid, PDO::PARAM_INT);
$query->bindParam(':itemdeleted', $itemdeleted, PDO::PARAM_INT);
$query->bindParam(':itemfirstothers', $itemfirstothers, PDO::PARAM_INT);
$query->execute();

$data = array();
$data2 = array();

$numbering = 0; //for item count
$count = 1; //counter use for background color
while ( $row2 = $query->fetch() ) {

if ( empty($data[ $row2['projectscostbreakdown_areaname'] ]) ) {
    $data[ $row2['projectscostbreakdown_areaname'] ]= array();
    $data2[ $row2['projectscostbreakdown_itemdescription'] ][ $row2['projectscostbreakdown_qty'] ]= array();
}

if ( empty( $data[ $row2['projectscostbreakdown_areaname'] ][ $row2['projectscostbreakdown_itemname'] ] ) ) {
    $data[ $row2['projectscostbreakdown_areaname'] ][ $row2['projectscostbreakdown_itemname'] ] = array();
    $data2[ $row2['projectscostbreakdown_itemdescription'] ][ $row2['projectscostbreakdown_qty'] ]= array();
}
    $data[ $row2['projectscostbreakdown_areaname'] ][ $row2['projectscostbreakdown_itemname'] ][] = $row2['projectscostbreakdown_totalcost'];
    $data2[ $row2['projectscostbreakdown_itemdescription'] ][ $row2['projectscostbreakdown_qty'] ]= array();
}
print '<table width="100%" border="0"><tbody>';
$totalSum = 0;

foreach ( $data as $area => $item ) {
print '<tr style="background-color: white;"><td colspan="7" style="text-align: left;"><br /><br /><b><u>'. $area .'</u></b></td></tr>';
print '<tr style="background-color: #AAAAAA; text-align: center;">
  <td width="20%""><b>Item name</b></td>
  <td width="30%"><b>Description</b></td>
  <td width="5%"><b>Qty.</b></td>
  <td width="10%"><b>Cost/Piece</b></td>
  <td width="10%"><b>Subtotal</b></td>
  <td width="10%"><b>Budget</b></td>
  <td width="15%"><b>Note /<br / >Entered by</b></td>
</tr>';
$totalArea = 0;

foreach ( $item as $item => $totalcost ) {
    //while ( $data = $query->fetch() ) {
    $numbering++;
    $count++;
    $class = ($count%2 == 0)? 'white': '#CCCCCC';
    $sum = array_sum( $totalcost );
    print '<tr style="background-color: '.$class.'">';
    print '<td style="vertical-align: top; text-align: left;">'. $numbering .'. '. $item . '</td>';
    print '<td style="vertical-align: top; text-align: left;">';
    print_r($data2);
    print '</td>';
    print '<td style="vertical-align: top; text-align: right;"></td>';
    print '<td style="vertical-align: top; text-align: right;"></td>';
    print '<td style="vertical-align: top; text-align: right;">'. number_format($sum, 2,'.', ',') . '</td>';
    print '<td style="vertical-align: top; text-align: right;"></td>';
    print '<td style="vertical-align: top; text-align: left;"></td>';
    print '</tr>';
    $totalArea += $sum;
}
print '<tr style="background-color: lightgray; text-align: right;" ><td colspan="6">Section Total: </td><td>'. number_format($totalArea, 2,'.', ',') . '</td></tr>';
$totalSum += $totalArea;
}
print '<tr style="background-color: lightblue; text-align: right;" ><td colspan="6"><b>Grand Total: </b></td><td><b>'. number_format($totalSum, 2,'.', ',') . '</b></td></tr>';
echo '</tbody>
</table>';
?>

更新 输出现在看起来像这样。 我需要在输出中包含描述和数量,但不知道该怎么做。

第 1 部分
项目名称-----描述-----数量-----小计
项目 1---------------------------------------------1000
第 2 项------------------------------------------------------2000
----------------------------------部分总数:3000

第 2 部分
项目名称-----描述-----数量-----小计
第 3 项---------------------------------1000
----------------------------------部分总数:1000
------------------------------------------------总计:4000

【问题讨论】:

  • 您能否展示您的结果如何以及您的预期?我会更容易理解。
  • 查看更新。谢谢。
  • 你能让你的数据库结构更易读吗? :)
  • 但也许你能给我看看它目前的样子和你想要的样子吗?我仍然很难完全理解你的问题。 :)
  • 输出看起来像链接。但我需要更多数据来展示。比如描述和数量。 i.imgur.com/55bUidK.jpg 谢谢

标签: php mysql foreach


【解决方案1】:

完整的代码(更结构化,修复的错误):

<?php

$projectsid = $_GET['projectrfpid'];
$itemdeleted = 1;
$itemfirstothers = 'OTHERS';
$query = $conn->prepare('SELECT projectscostbreakdown_id,
projectscostbreakdown_projectid,
projectscostbreakdown_areaname,
projectscostbreakdown_itemname,
projectscostbreakdown_itemdescription,
projectscostbreakdown_qty,
projectscostbreakdown_costpiece,
projectscostbreakdown_budgeted,
projectscostbreakdown_totalcost,
projectscostbreakdown_note,
projectscostbreakdown_addedby,
projectscostbreakdown_addeddate,
projectscostbreakdown_deleted,
projectscostbreakdown_lastedit,
projectscostbreakdown_lasteditby
FROM projectscostbreakdown WHERE projectscostbreakdown_projectid=:projectsid && projectscostbreakdown_deleted=:itemdeleted ORDER BY projectscostbreakdown_areaname=:itemfirstothers, projectscostbreakdown_areaname ASC, projectscostbreakdown_id DESC');
$query->bindParam(':projectsid', $projectsid, PDO::PARAM_INT);
$query->bindParam(':itemdeleted', $itemdeleted, PDO::PARAM_INT);
$query->bindParam(':itemfirstothers', $itemfirstothers, PDO::PARAM_INT);
$query->execute();

$data = array();
$data2 = array();

$numbering = 0; //for item count
$count = 1; //counter use for background color
$itemData = $query->fetchAll();
$query->execute();

while ($row2 = $query->fetch()) {
    if (empty($data[$row2['projectscostbreakdown_areaname']]) ) {
        $data[$row2['projectscostbreakdown_areaname']]= array();
        $data2[$row2['projectscostbreakdown_itemdescription']][$row2['projectscostbreakdown_qty']] = array();
    }

    if (empty($data[$row2['projectscostbreakdown_areaname']][$row2['projectscostbreakdown_itemname']])) {
        $data[$row2['projectscostbreakdown_areaname']][ $row2['projectscostbreakdown_itemname']] = array();
        $data2[$row2['projectscostbreakdown_itemdescription']][$row2['projectscostbreakdown_qty']]= array();
    }

    $data[$row2['projectscostbreakdown_areaname']][$row2['projectscostbreakdown_itemname']][] = $row2['projectscostbreakdown_totalcost'];
    $data2[$row2['projectscostbreakdown_itemdescription']][$row2['projectscostbreakdown_qty']] = array();
}

print '<table width="100%" border="0"><tbody>';
$totalSum = 0;

foreach ( $data as $area => $item ) {
    print '<tr style="background-color: white;"><td colspan="7" style="text-align: left;"><br /><br /><b><u>'. $area .'</u></b></td></tr>';
    print '<tr style="background-color: #AAAAAA; text-align: center;">
      <td width="20%""><b>Item name</b></td>
      <td width="30%"><b>Description</b></td>
      <td width="5%"><b>Qty.</b></td>
      <td width="10%"><b>Cost/Piece</b></td>
      <td width="10%"><b>Subtotal</b></td>
      <td width="10%"><b>Budget</b></td>
      <td width="15%"><b>Note /<br / >Entered by</b></td>
    </tr>';
    $totalArea = 0;

    foreach ( $item as $item => $totalcost ) {
        $count++;
        echo $numbering.' ';
        $class = ($count % 2 == 0) ? 'white' : '#CCCCCC';
        $sum = array_sum($totalcost);
        print '<tr style="background-color: '.$class.'">';
        print '<td style="vertical-align: top; text-align: left;">'. $numbering .'. '. $item . '</td>';
        print '<td style="vertical-align: top; text-align: left;">'.$itemData[$numbering]['projectscostbreakdown_itemdescription'].'</td>';
        print '<td style="vertical-align: top; text-align: right;"></td>';
        print '<td style="vertical-align: top; text-align: right;"></td>';
        print '<td style="vertical-align: top; text-align: right;">'. number_format($sum, 2,'.', ',') . '</td>';
        print '<td style="vertical-align: top; text-align: right;"></td>';
        print '<td style="vertical-align: top; text-align: left;"></td>';
        print '</tr>';
        $numbering++;
        $totalArea += $sum;
    }

    print '<tr style="background-color: lightgray; text-align: right;" ><td colspan="6">Section Total: </td><td>'. number_format($totalArea, 2,'.', ',') . '</td></tr>';
    $totalSum += $totalArea;
}
print '<tr style="background-color: lightblue; text-align: right;" ><td colspan="6"><b>Grand Total: </b></td><td><b>'. number_format($totalSum, 2,'.', ',') . '</b></td></tr>';
echo '</tbody></table>';
?>

基本上,我所做的(这可能不是最好的选择,但我想不出更好的选择)是在执行$query-&gt;execute(); 之后使用$itemData = $query-&gt;fetchAll();。现在,如果我们保持一切不变,表格将是空的,因为指针位于最后一个元素。因此,我们必须通过在$itemData = $query-&gt;fetchAll(); 后面写一个额外的$query-&gt;execute(); 来再次执行相同的查询。

现在我们有了与您的示例基本相同的内容,但多了一个变量$itemData,其中包含有关项目的所有信息。现在我们可以使用$itemData[$numbering]['projectscostbreakdown_itemdescription']来显示描述、数量等,其中$numbering代表数组的索引号。

【讨论】:

  • 您好 Edvin,非常感谢您的帮助。不幸的是它仍然不起作用,没有错误但没有项目出现。我从这里*.com/questions/3707613/… 获得了代码,然后修改它以满足我的要求。此代码有效,但我需要显示更多数据(描述、数量等)。一个item会有qty、price和totalcost(qty*price保存在数据库中),$sum = array_sum($totalcost),将每个section每个item的所有总成本相加。
  • @user366966 我明白了。 while 指针位于最后一个元素,因此它不返回任何内容。如果您尝试使用$data = $query-&gt;fetchAll();,然后使用相同的foreach(),会怎样?
  • 它什么也不返回。你认为我可以添加我需要在“while”中返回的项目,比如 $data2[ $row2['projectscostbreakdown_qty'] ]= array();因为它在那里它只工作但不知道如何添加。我试过了,但它说未定义索引 projectcostbreakdown_qty 在 foreach 所在的行中,所以我不能在 foreach 中声明它。
  • @user366966 我实际上可能会解决这个问题,但是我需要该表(至少几行)中的 SQL 虚拟数据(导出)。然后我可以在我的测试数据库中检查自己。
  • 非常感谢您的帮助,这里的文本文件为 sql,您可以复制并导入 textuploader.com/58zlh 我使用 projectid 42 作为示例,以方便您使用。