将商品添加到购物车时出现重复 (php)

Duplication when adding goods to the cart (php)

您需要在购物车中创建一个商品计数器。当我将商品添加到购物车时,它被复制了。在 $_SESSION ['products'] 中出现 [0],其中也包含一个数字。我找到了摆脱它的方法: unset($_SESSION['products'][0]);但我不确定这是对的。我该怎么办?

这个文件是 order.php :

    <?php
class Order{
    static function addInOrder($id){
        $id= intval($id);
        $productsInOrder=array();
        if(isset($_SESSION['products'])){
            $productsInOrder=$_SESSION['products'];
        }

        if(array_key_exists($id, $productsInOrder)){
            $productsInOrder[$id]++;
        }

        else{
            $productsInOrder[$id]=1;
        }

        $_SESSION['products']=$productsInOrder;

    }

    static function orderCount(){
        if(isset($_SESSION['products'])){
            unset($_SESSION['products'][0]);
            $count=0;
            foreach ($_SESSION['products']as $id=>$value){
                $count+=$value;
            }
            return $count;
        }

        else{
            return 0;
        }
    }


}


?>

orderController.php :

    <?php
class OrderController{
    public function actionSend($id){
        Order::addInOrder($id);
        $referer=$_SERVER['HTTP_REFERER'];
        header("location: $referer");
    }
}
?>

您可能向 addInOrder 发送了错误的信息,而没有看到该变量是什么,也不知道它是什么。如果没有更多的代码,就无法知道它来自哪里。即使您可以 运行 该网站,也很难追踪到这些东西(但我有一些提示,请参见下文)。

当您使用 intval 转换像 "foo" 这样的字符串时,例如 returns 0。但是如果 id 是 falsy 你可以放弃这个函数 例如:

  //this is just a simplified example to show how to bail out of the method
 function addInOrder($id){
    if(false ==($id = intval($id))) return;
    echo $id."\n";
    //.....
 }

addInOrder(1);
addInOrder("foo");

输出(returns 在 0 上)

 1

Sandbox

这确实不是解决方案,因为您应该找到错误的调用。

function addInOrder($id){
    if(false ==($id = intval($id))){
        try{
           throw new Excepton(__METHOD__." called with invalid argument[$id]");

        }catch(Exception $e){
             echo $e->getMessage()."\n";
             echo $e->getTraceAsString();
             exit;
        }
    }
    echo $id."\n";
 }

现在当它发生时,您的网站会爆炸(开玩笑)但它会崩溃,但是您会得到一个很好的堆栈跟踪,您可以使用它来查找调用的来源,以便您可以解决实际问题。

基本上无论出于何种原因,您的方法中的 $id 变量都会得到 0。最可能的原因(除了你发送 0)是其他原因,然后一个数字被设置到它然后用 intval

转换为 0

In $_SESSION ['products'] appears [0]

例如,如果您调用 addInOrder("foo"),您将获得一个包含数字和索引 0 的数组项。

我无法在沙盒中使用 $_SESSION,但我们可以使用 global $session 复制它的工作方式。这样我就可以重现(我认为你在说什么):

function addInOrder($id){
        global $session;
        $id= intval($id);
        $productsInOrder=array();
        if(isset($session['products'])){
            $productsInOrder=$session['products'];
        }

        if(array_key_exists($id, $productsInOrder)){
            $productsInOrder[$id]++;
        }else{
            $productsInOrder[$id]=1;
        }

        $session['products']=$productsInOrder;
}

addInOrder(1);
print_r($session);
echo "\n---------------------------------\n";
addInOrder("foo");
print_r($session);

输出:

Array
(
    [products] => Array
        (
            [1] => 1
        )

)

---------------------------------
Array
(
    [products] => Array
        (
            [1] => 1
            [0] => 1
        )

)

Sandbox

就我个人而言,每当此方法在 intval 之后得到 falsy 的内容时,我都会抛出错误,因为它永远不会发生,除非调用搞砸了(你没有向它发送 ID) .但我应该提到永远不要在生产服务器上显示堆栈跟踪,因为参数可以包含数据库密码等内容...

希望对您有所帮助。