douyuefei3546 2018-01-23 19:58
浏览 50
已采纳

在PHP中的数组列表中更改单个数组的值

What I'm attempting to do is change the value of a single array within my list of arrays (which I use for saving products in a session) by getting it's unique product ID.

I'm using the following code:

function removeProductFromBasket($itemID)
{
// Loop through products
foreach($_SESSION['shopping_cart'] as $arr => $prod) {

    // Check if product is already included
    if ($prod['productid'] == $itemID) {
        echo $itemID;
        $_SESSION['shopping_cart'][$arr]['quantity'] = 0;
    }
}
}

And my array looks like this:

Array ( [0] => Array ( [productid] => 18 [quantity] => 0 ) [1] => Array ( [productid] => 2 [quantity] => 0 ) [2] => Array ( [productid] => 4 [quantity] => 4 ) ) 

Currently the function is being called using

href="'.removeProductFromBasket($productID).'"
  • 写回答

1条回答 默认 最新

  • douyuan3842 2018-01-23 20:55
    关注

    Seperate the concerns

    The first problem I see with the current implementation, is that it "magically" acts on the $_SESSION variable. By doing so, you limit your ability to modify the logic in the future since the implentation of the logic is so tightly soupled with how the data is being stored. You also run the risk of forgetting that you had a function somewhere else in the code that also altered the value of $_SESSION, thus making the behavior of removeProductFromBasket unpredictable and vulnerable to bugs.

    To fix this issue, you need to decouple your function from the $_SESSION. You can achieve this by adding a parameter to the function signature that takes in the shopping cart as an array.

    function removeProductFromBasket($cart, $itemID)
    {
        // Loop shopping cart
        foreach($cart as $key => $productArr) {
    
            // Check if product is already included
            if ($productArr['productid'] == $itemID) {
                echo $itemID;
                $cart[$key]['quantity'] = 0;
            }
        }
    
        return cart;  // return the updated cart
    }
    

    By modifying the code in this way allows you to handle the $_SESSION elsewhere, maybe in a wrapper object or something of the sort without affecting the logic of the item removal of the shopping cart. It also allows you to more easily change how the information is persisted. Say you wanted to use Redis or some other data store, you would have less lines to modify to make the change.

    Calling the function

    The other problem I see with your current implementation is the way the function is called. From your sample code, I'm guessing that the full line ressembles something like this:

    echo '<a href="'.removeProductFromBasket($productID).'">Remove this</a>
    

    Since PHP is executed on the server side, what this is doing is calling the function removeProductFromBasket when the page gets loaded. This means that by the time the page is rendered and loaded on the client side, the item has already been removed, and the href will look like href="12345" du to the echo in your function.

    Instead, you should be echoing a valid url to the item removal logic, with Item ID proerly concatenated as a parameter.

    form.php

    foreach($_SESSION['shoppingCart'] as $key => $item) {
        echo '<a href="http://www.example.com/path/to/file.php?itemId='.$item['productid'].'">Remove this</a>
    }
    

    item_removal.php

    <?php
        // Make sure the session is started, $_GET is not empty and any other validation
    
        function removeProductFromBasket($cart, $itemID)
        {
            // Loop shopping cart
            foreach($cart as $key => $productArr) {
    
                // Check if product is already included
                if ($productArr['productid'] == $itemID) {
                    // the echo is no longer needed
                    $cart[$key]['quantity'] = 0;
                }
            }
    
            return cart;  // return the updated cart
        }
    
        $_SESSION['shoppingcart'] = removeProductFromBasket($_SESSION['shoppingcart'], $_GET['itemId']);
    ?>
    

    Of course there is still room for improvement, for example by creating an object ShoppingCart and a wrapper Session around the $_SESSION variable, but this should be a good place for you start and build upon.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 想问一下树莓派接上显示屏后出现如图所示画面,是什么问题导致的
  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号