【问题标题】:FOREACH loop within WHILE loop Getting Run Multiple Times - PHPWHILE 循环中的 FOREACH 循环多次运行 - PHP
【发布时间】:2015-07-27 18:38:00
【问题描述】:

我正在尝试通过 php 运行 mysqli 查询,该查询将根据所选内容更新项目的数量。因此,如果用户选择两个数量的项目,该数量应该减少两个。我可以用这段代码成功地做到这一点:

$postparts = $_POST['part_name']; <-- This is an array of the items chosen
$postqty = $_POST['qty']; <-- This is an array of the qty of each item chosen

$combine = array_combine($postparts, $postqty); <-- I combine the arrays to match the qty to the item that was chosen.  

foreach ($combine as $part=>$qty)
    {
        $update = <<<SQL
UPDATE `Houston` SET `qty` = (`qty`-?) WHERE `partnumber` = ?;
SQL;
        $result = $mysqli->prepare($update);
        $result->bind_param("is", $qty, $part);
        $result->execute();
    }

上面的代码将从选择的项目中减去适当的数量 - 这里没有问题。但是,我需要执行一个额外的检查,这样如果两个人同时检查同一个项目,第一个会得到一个成功的结果,但是如果项目的数量是 0,那么由于第一个结帐过程,第二个人会失败。我试着这样做:

$postparts = $_POST['part_name'];
$postqty = $_POST['qty'];

$partarray = array();
foreach ($postparts as $part => $id)
{
    $finalpart = ($postparts[$part]);
    $stuff = explode(',', $finalpart);
    $partarray = array_merge($partarray, $stuff);
}

$combine = array_combine($postparts, $postqty);
$in = implode(',', array_fill(0, count($partarray), '?'));
$check = <<<SQL
SELECT * FROM `Houston` WHERE `partnumber` in ($in);
SQL;

$statcheck = $mysqli->prepare($check);
$statcheck->bind_param(str_repeat('s', count($partarray)), ...$partarray);
$statcheck->execute();
$statcheck->store_result();
$statcheck->bind_result($id, $partcat, $partnumber, $partqty);
while ($statcheck->fetch())
{
    if ($partqty > 0)
    {
        foreach ($combine as $part=>$qty)
        {
            $update = <<<SQL 
UPDATE `Houston` SET `qty` = (`qty`-?) WHERE `partnumber` = ?;
SQL;
            $result = $mysqli->prepare($update);
            $result->bind_param("is", $qty, $part);
            $result->execute();
        }
   }
   if ($partqty == 0)
   {
        header("location:error.php");
   }
}

所以这个“几乎”有效 - 除了 foreach 循环运行多次。假设用户签出两个项目 - 然后 foreach 循环运行两次 - 所以订购的数量最终会为每个项目加倍(如果 3 个项目,则数量增加三倍,等等)。我怀疑这种行为的原因是因为我在 while 循环中运行 foreach 循环,但我不确定如何解决这个问题以使其正常工作。有人知道怎么做吗?

【问题讨论】:

  • 快速浏览后,我认为您根本不需要 foreach!?您正在对同一数据集进行两次迭代。
  • 您可能是对的,但是我该如何进行 mysqli 更新呢?我需要确保从正确的项目中减去正确的数量。我想过用 qty 做与零件相同的事情,并将其放在 while 循环中……我想我应该尝试一下,但不确定如何使用 str_repeat 绑定两个变量?也许我必须走 PDO 路线?

标签: php loops mysqli foreach


【解决方案1】:

你对准备好的语句的理解完全错误。顾名思义,您只需准备一次。

此外,选择数据只是为了更新它是没有意义的。需要查什么,都得通过SQL查询来查。

$combine = array_combine($postparts, $postqty);
$sql = "UPDATE Houston SET qty = qty-?) WHERE partnumber=? AND qty > 0";
$stmt = $mysqli->prepare($sql);
$stmt->bind_param("is", $qty, $part);
foreach ($combine as $part=>$qty)
{
    $stmt->execute();
}

我需要执行一个额外的检查,这样如果两个人同时签出同一个项目,第一个会得到一个成功的结果,但是如果项目的数量是 0,因为第一次结帐过程中,第二个人会失败。

您需要为此锁定表。如果您确实需要这样的检查。

要查看更新是否成功,请使用PDOStatement::rowCount()

【讨论】:

  • 啊...这让它变得简单多了。谢谢!我会试试这个。
  • 所以这种方法可行,但是如果用户在尝试结帐时数量已设置为 0,我该如何将用户引导至错误页面?
  • @Wes - 重定向完全是一个不同的问题。如果您在已经存在的问题中找不到answer you're looking for,请随意开始您自己的问题。 (如果以后其他人有类似的问题,他们不会知道在这个特定的问答中检查 cmet,所以除了你之外,在这里回答对任何人都没有好处。)
【解决方案2】:

我能够找到一个可行的解决方案,但不确定它是否是最优雅的解决方案。如果有人有更好的想法,请告诉我。

$postparts = $_POST['part_name'];
$postqty = $_POST['qty'];
$combine = array_combine($postparts, $postqty);

$update = <<<SQL
UPDATE `Houston` SET `qty` = (`qty`-?) WHERE `partnumber` = ?;
SQL;
$result = $mysqli->prepare($update);
$result->bind_param("is", $qty, $part);

$check = <<<SQL
SELECT * FROM `Houston` WHERE `partnumber` = ?;
SQL;
$checkpart = $mysqli->prepare($check);
$checkpart->bind_param('s', $part);

foreach ($combine as $part=>$qty)
{
    $checkpart->execute();
    $checkpart->store_result();
    $checkpart->bind_result($id, $partcat, $partnumber, $partqty);

    if ($checkpart->fetch())
    {
        if ($partqty > 0)
        {
            $result->execute();
        }
        elseif ($partqty == 0)
        {
            header("location:error.php");
        }
    }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-10-19
    • 2017-05-28
    • 2015-07-03
    • 2016-06-19
    • 2012-10-02
    • 1970-01-01
    • 2013-10-01
    • 1970-01-01
    相关资源
    最近更新 更多