Updating the item value in the array, and how can I append the item instead of overwriting it?

sarah kim

I created a shopping cart, and whenever there is an item, I will increase the quantity. And if the item is not in the cart, I am pulling the information of the item from the database. However, the while loop keeps overwriting the SESSION variable instead of appending it. This is my code:

if (isset($_GET['bookId'])) {
        $bookId = $_GET['bookId'];
        if (isset($_SESSION['cartItems'])) {
            echo "cart NOT empty";
            $cartItems = $_SESSION['cartItems'];

            // Loop through the cartItems array.
            $found = 0;
               
                foreach ($cartItems as &$cartItem) {
                    // If the book is already in the cart items
                    if ($cartItem['bookId'] == $_GET['bookId']) {
                        $cartItem['quantityInput'] += 1;
                        $found = 1;}   

                   // If the book is not in the cart item, then append the book.
                    elseif ($found == 0) {
                        //add the book
                        echo "new book!";
                        // Connect to Database to get data. Output is $result

                        ****THIS IS THE PART GOING WRONG!*******
                        while ($book = $result -> fetch_assoc()) {
                            echo "This part is not working well, IT OVERWRITES THE ARRAY!";

                            $cartItem = array('bookId'=>$book['bookId'], 'title'=>$book['title'], 'price'=>$book['price'], 'quantityInput'=>1);
                            $cartItems[$book['bookId']] = $cartItem;

                            echo $cartItems[$book['bookId']]['title'];
                        }
                    }
            }

        } else {
            echo "cart empty";
            $cartItems = array();
            // Add the book into cart item
            // This part I connect with DB to get data, output is $result

            while ($book = $result -> fetch_assoc()) {
                $cartItem = array('bookId'=>$book['bookId'], 'title'=>$book['title'], 'price'=>$book['price'], 'quantityInput'=>1);
                $cartItems[$book['bookId']] = $cartItem;
            }
        }
        $_SESSION['cartItems'] = $cartItems;
        print_r($cartItems);
    }

I'm confused because I have the key which is bookId, and all of item has different id numbers. So it should not overwrite... What am I missing here? How can I fix this problem? Below is the output of the array when I print out the cart item at the end with print_r($cartItems);

( [2] => Array ( [bookId] => 1 [title] => The Royal Easter [price] => 14.99 [quantityInput] => 1 ) [1] => Array ( [bookId] => 1 [title] => The Royal Easter [price] => 14.99 [quantityInput] => 2 )
El_Vanja

You have two big culprits in your code. The first one is a flawed control structure:

foreach ($cartItems as &$cartItem) {
    if ($cartItem['bookId'] == $_GET['bookId']) {
        $cartItem['quantityInput'] += 1;
        $found = 1;
    }   
    // If the book is not in the cart item, then append the book.
    elseif ($found == 0) {
        // add a whole new book
    }
}

Since this is inside a loop, the elseif portion will execute each time the id doesn't match, until the book is found. If the book was not present, it would execute for every element of the cart.

That's where the second culprit comes in. You pass the element as a reference in your loop, meaning any operation over that element would change it. Since you were doing exactly that in the elseif branch by assigning it a new value ($cartItem = ...), it would ultimately result in it being overwritten.

What you actually need to do is extract the contents of that branch outside the loop, because you only want it to run once - if the book was not found:

foreach ($cartItems as &$cartItem) {
    // If the book is already in the cart items
    if ($cartItem['bookId'] == $_GET['bookId']) {
        $cartItem['quantityInput'] += 1;
        $found = 1;
        /* Adding a break here would stop the loop once the book was found.
        It would be a logical addition if no special cases exist where
        an item can be added twice independently (seems like that's what
        you're going for, no duplicates in the cart). */
    }
}
// If the book is not in the cart item, then append the book.
if ($found === 0) {
    // everything that was in your elseif branch
}

This should solve your issue. But please consider the following improvements to your code...

This code block is repeated twice (both when the book is not found and when the cart is empty):

while ($book = $result -> fetch_assoc()) {
    $cartItem = array('bookId'=>$book['bookId'], 'title'=>$book['title'], 'price'=>$book['price'], 'quantityInput'=>1);
    $cartItems[$book['bookId']] = $cartItem;
}

The sensible thing would be to extract any duplicating code into a function and just call it multiple times. But in your case this duplication can be eliminated. You need the exact same operation in those two cases and you can have the same code execute it:

if (isset($_GET['bookId'])) {
    $bookId = $_GET['bookId'];
    $found = 0;
    foreach ($_SESSION['cartItems'] ?? [] as $cartItem) {
        if ($cartItem['bookId'] == $bookId) {
            $_SESSION['cartItems'][$bookId]['quantityInput']++;
            $found = 1;
            break;
        }
    }
    if ($found === 0) {
        // your query code here
        while ($book = $result->fetch_assoc()) {
            $newCartItem = array_merge($book, ['quantityInput' => 1]);
            $_SESSION['cartItems'][$book['bookId']] = $newCartItem;
        }
    }
}

Note several things about the refactored solution:

  • I eliminated the check to see if the cart was empty or not. That is really not relevant to your case. All you need to think about is checking if the book exists in the cart. Whether it doesn't because it's empty or simply because other books are in there is all the same for your logic - you just need to append a new item.
  • $_SESSION['cartItems'] ?? [] is the equivalent of isset($_SESSION['cartItems']) ? $_SESSION['cartItems'] : [] and will tell the loop to use an empty array if there is no cart, which will in turn just skip the loop and go straight to adding the new element.
  • I eliminated the passing by reference and modified the session variable directly.
  • When adding a new book, I renamed the variable from $cartItem to $newCartItem. I see it as a good practice not to reuse variable names, it can lead to unexpected results due to accidental reassignments.
  • $newCartItem = array_merge($book, ['quantityInput' => 1]); does the same thing as your code did with array('bookId'=>$book['bookId'], 'title'=>$book['title'], 'price'=>$book['price'], 'quantityInput'=>1) - it uses the same keys and values of the book, just adding quantity to it.

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

InnerHTML Append Item instead of Replace

分類Dev

how can I use selected menu item value inside userdefined method in android

分類Dev

Create array if not exists or append item to existing

分類Dev

How can i give the selected attribute to a item in an array fetched from mysql database

分類Dev

Python: How to append list item to dictionary if item equals key?

分類Dev

how to append an item to a list in an existing handelbar template?

分類Dev

How do I create an array of one item in Go?

分類Dev

how do I perform a function on an item in a jquery array

分類Dev

How can I figure out if the current item is the last item in a section of a ListView

分類Dev

After drag and drop Recyclerview item, how can I provide the updated Position of a list item at onbind method of an adapter

分類Dev

How can i use espresso to click an item from a list view based on item' text?

分類Dev

How can I change the NavigationView's item text size?

分類Dev

How can i enter only one data per Item in Grid

分類Dev

How can I search in Label[] for item.Text?

分類Dev

How can I get the selected item from List in React?

分類Dev

How can I store the links found for each item searched into a list?

分類Dev

How can I make an enum item have items of another enum?

分類Dev

How can i target an individual item in a titanium alloy listview?

分類Dev

How can i check if an item is part of a specific menu [Joomla 3.3]

分類Dev

How can I get a listbox's selected item binded element?

分類Dev

The selected item in a listbox is null how can i fix that?

分類Dev

How can I remove every other item from a Sass list?

分類Dev

How to check if an item in an array is a letter?

分類Dev

Can I delete an item of a queryset in python but without deleting that item on the database?

分類Dev

How to add an item to an array of array list

分類Dev

Can I get the nth item of a firebase "query"?

分類Dev

How do I get all item of an array which doesn't exists in another array

分類Dev

How to append an item in a list for use later in a If-statement

分類Dev

Updating an ImageView in a RecyclerView on item click

Related 関連記事

  1. 1

    InnerHTML Append Item instead of Replace

  2. 2

    how can I use selected menu item value inside userdefined method in android

  3. 3

    Create array if not exists or append item to existing

  4. 4

    How can i give the selected attribute to a item in an array fetched from mysql database

  5. 5

    Python: How to append list item to dictionary if item equals key?

  6. 6

    how to append an item to a list in an existing handelbar template?

  7. 7

    How do I create an array of one item in Go?

  8. 8

    how do I perform a function on an item in a jquery array

  9. 9

    How can I figure out if the current item is the last item in a section of a ListView

  10. 10

    After drag and drop Recyclerview item, how can I provide the updated Position of a list item at onbind method of an adapter

  11. 11

    How can i use espresso to click an item from a list view based on item' text?

  12. 12

    How can I change the NavigationView's item text size?

  13. 13

    How can i enter only one data per Item in Grid

  14. 14

    How can I search in Label[] for item.Text?

  15. 15

    How can I get the selected item from List in React?

  16. 16

    How can I store the links found for each item searched into a list?

  17. 17

    How can I make an enum item have items of another enum?

  18. 18

    How can i target an individual item in a titanium alloy listview?

  19. 19

    How can i check if an item is part of a specific menu [Joomla 3.3]

  20. 20

    How can I get a listbox's selected item binded element?

  21. 21

    The selected item in a listbox is null how can i fix that?

  22. 22

    How can I remove every other item from a Sass list?

  23. 23

    How to check if an item in an array is a letter?

  24. 24

    Can I delete an item of a queryset in python but without deleting that item on the database?

  25. 25

    How to add an item to an array of array list

  26. 26

    Can I get the nth item of a firebase "query"?

  27. 27

    How do I get all item of an array which doesn't exists in another array

  28. 28

    How to append an item in a list for use later in a If-statement

  29. 29

    Updating an ImageView in a RecyclerView on item click

ホットタグ

アーカイブ