我正在创建一个简单的订单车。
从本质上讲,用户单击订单,产品id将作为数组添加到会话变量($order(中。查看"cart"时,会进行检查,如果会话变量中的值等于mysql表中特定行的id,则该特定行将作为已排序的项返回。对于会话变量中的每个值,此过程都应该重复出现。
以下是我正在与之斗争的代码:
foreach ($order as $item)
{
while($row = mysql_fetch_assoc($productsSql))
{
$itId = $row['id'];
$itDesc = $row['desc'];
$itPrice1 = $row['price1'];
if ($item == $itId)
{
$pageContent .= '
<tr>
<td>'.$itDesc.'</td>
<td>
R'.number_format($itPrice1, 2).'
</td>
</tr>
';
}
}
}
"$orders"变量如下:
session_start();
if (!isset($_SESSION['order']))
{
$_SESSION['order'] = array();
}
有人能发现这个问题吗?
$productsQuery = 'SELECT `id`, `refCode`, `desc`, `pack`, `measure`, `quantity`, `deptCode`, `taxable`, `price1`, `price2`, `crdCode`, `cost1`, `cost2` FROM `products` ORDER BY `desc` ';
$productsSql = mysql_query($productsQuery) or die(mysql_error());`
while($row = mysql_fetch_assoc($productsSql))
这不会在每个$item
中重现,所以在foreach之前将行保存在数组中,并将此while
替换为foreach
。
尝试这个
mysql_data_seek($productsSql,0(;
foreach ($order as $item)
{
mysql_data_seek( $productsSql, 0); //<- this line, to reset the pointer for every EACH.
while($row = mysql_fetch_assoc($productsSql))
{
$itId = $row['id'];
$itDesc = $row['desc'];
$itPrice1 = $row['price1'];
if ($item == $itId)
{
$pageContent .= '
<tr>
<td>'.$itDesc.'</td>
<td>
R'.number_format($itPrice1, 2).'
</td>
</tr>
';
}
}
}
希望对有所帮助
您还没有指定$productsSql
的内容,但包含它的行看起来是错误的。
如果$productsSql
包含SQL代码,那么它根本不起作用,因为mysql_fetch_assoc()
需要数据库资源。要获得资源,您需要使用SQL代码调用mysql_query()
。
假设您在引用的代码之外调用了mysql_query()
,并且$productsSql
确实包含结果资源,那么这仍然是错误的,因为您多次循环数据库结果(因为foreach
循环(,但没有重置或重新查询。
这样做的结果是,在foreach
的第一次迭代之后,while
循环将贯穿数据库查询中的所有结果,并将被设置到结果集的末尾。循环回到代码的顶部不会改变结果集的位置,所以当它第一次尝试在第二次循环中调用mysql_fetch_assoc()
时,它会说"我已经完成了",什么都不会发生。
如果希望foreach
循环的每次迭代都处理相同的结果集,则需要在启动while
循环之前重置DB指针。这可以通过mysql_data_seek()
函数来完成。
使用您提供的代码,这可能会达到您想要的效果。
然而,这可能不是达到你想要的结果的最有效的方法。不幸的是,如果没有看到更多的代码(特别是SQL查询和更多的数据结构(,很难更具体地说明如何改进它。
[EDIT]在OP将SQL查询添加到问题中后,我们可以更清楚地看到最佳操作方案是什么。
一个快速而肮脏的解决方案确实是使用mysql_data_seek()
,正如我上面解释的那样(如@Phoenix的代码所示(,但尽管这会使程序正常工作,但效率会非常低,尤其是在向数据库添加更多产品时。
实际需要的是从SQL查询本身开始对代码进行彻底的更改。
需要将查询更改为仅包括实际需要的项。这将使用WHERE
子句来完成,因此查询可能看起来像这样:
SELECT <lots of fields> FROM products WHERE id IN(5,7,9,<etc>)
这很容易生成,因为$orders
看起来是一个项目ID的数组,所以您可以简单地使用implode(',',$orders)
来制作一个适用于WHERE
子句的ID列表。(不过,您需要绝对确定它们都是数字ID,因为其他任何东西都会破坏SQL查询;如果您不确定,则应该首先对它们进行SQL转义(。
一旦获得了该列表,最好的方法是将DB值加载到内存数组中,然后使用foreach($order)
循环获取适当的数组元素。
所以你的最终代码看起来像这样:
$productsQuery = 'SELECT `id`, `refCode`, `desc`, `pack`, `measure`, `quantity`, `deptCode`, `taxable`, `price1`, `price2`, `crdCode`, `cost1`, `cost2` FROM `products` WHERE id IN('.implode(',',$orders).')';
$productsSql = mysql_query($productsQuery) or die(mysql_error());`
$data = array();
while($row = mysql_fetch_assoc($productsSql)) {
$data[$row['id']] = $row;
}
foreach($order as $item) {
$pageContent .= '
<tr>
<td>'.$row[$item]['desc'].'</td>
<td>
R'.number_format($row[$item]['price'], 2).'
</td>
</tr>
';
}