0

I am working on a shopping cart project and have a $_SESSION['productSummary'] array that looks like this.

[productSummary] => Array
        (
            [0] => Array
                (
                    [name] => Individual Coins
                    [code] => 8774
                    [IDs] => Array
                        (
                            [0] => 8774
                            [1] => 8775
                            [2] => 8778
                            [3] => 8765
                        )

                    [pluID] => 6105
                    [qty] => 4
                    [finalPrice] => 0.0000
                    [listPrice] => 0.0000
                    [shipping] => 0.0000
                )

            [1] => Array
                (
                    [name] => Business Package - 5,000
                    [code] => 8770
                    [IDs] => Array
                        (
                            [0] => 8770
                        )

                    [pluID] => 6087
                    [qty] => 1
                    [finalPrice] => 125.0000
                    [listPrice] => 125.0000
                    [shipping] => 0.0000
                )

        )

When the user wants to remove an item #8778 from the cart, I need to find the value of the index key for '8778' so I can remove that value from the array of IDs.

Here is the snip of code I have so far. I am getting good values for $matchingKey but $matchingKey2 is always empty.

// Find the key for the parent array
$matchingKey = array_search(8778, array_column($_SESSION["productSummary"], 'IDs'));

// Find the key for the element in the nested IDs array
$matchingKey2 = array_search(8778, array_column($_SESSION['productSummary'][$matchingKey]['IDs']));

// If it found a match, unset that element
if(!empty($matchingKey2)) {
     unset($_SESSION["productSummary"][$matchingKey]['IDs'][$matchingKey2]);
}

// Reindex the array
$_SESSION["productSummary"][$matchingKey]['IDs'] = array_values($_SESSION["productSummary"][$matchingKey]['IDs']);

I was expecting

$matchingKey2 = array_search(8778, array_column($_SESSION['productSummary'][$matchingKey]['IDs']));

to return the value of 2 in this example, but instead if comes back as NULL

UPDATE: SOLVED Based on the answers given, I updated my code to this and it seems to be working as expected now. (or at least until I break it again.) Thanks All

// $results is pulled from query of database based on a packageID - Short version is it puts all packaged inventory items in the cart and allows all to be taken out of the cart in as a group.

foreach ($results as $cartItem) {
           
           // set cart time in the database back to NULL so it will appear in the store again
           $query = "hidden";
           dbWriteQuery($query);
               
           // Remove item from SESSION['products']
           $indexA = array_search($cartItem['inventoryID'], array_column($_SESSION["products"], 'code'));
   
           if($indexA !== false) { 
               unset($_SESSION["products"][$indexA]);
           }
           // Reindex the array
           $_SESSION["products"] = array_values($_SESSION["products"]);
   

           // Remove item (or reduce qty) from SESSION['productSummary']   
           foreach ($_SESSION["productSummary"] as $key => $product) {
               $indexB = array_search($cartItem['inventoryID'], $product['IDs']);
               
               //Found a matching element
               if ($indexB !== false) {
                   
                   // if count of $product['IDs'] > 1, reduce the qty and remove the inventoryID from ID's
                   if(count($product['IDs'])>1) {
                       //reduct the qty
                       $_SESSION['productSummary'][$key]['qty'] = $_SESSION['productSummary'][$key]['qty'] - 1;
                       
                       // remove the inventoryID from the IDs array
                       array_splice($_SESSION['productSummary'][$key]['IDs'], $indexB, 1);
                       
                       // set the 'code' value equal to the next element in the IDs array
                       $_SESSION['productSummary'][$key]['code'] = $_SESSION['productSummary'][$key]['IDs'][0];
                       
                   // else unset the whole element from ProductSummary
                   } else {
                       unset($_SESSION["productSummary"][$key]);
                       
                   }
                                       
                   break;
               }
           }
           
           // Reindex the array
           $_SESSION["productSummary"] = array_values($_SESSION["productSummary"]);
   
       }
Bo Harris
  • 1
  • 1
  • `array_search()` doesn't search nested arrays. I don't see how you could be getting a correct `$matchingKey`. – Barmar Dec 23 '22 at 22:25
  • 1
    What makes you think you're getting a good value for `$matchingKey`? When I try this I get `false`. If you use that as an array index it will be converted to `0`. – Barmar Dec 23 '22 at 22:29
  • @Barmar, I ran into that situation after posting this, but your explanation of converting false to 0 is helpful. I didn't know it did that. Thanks. – Bo Harris Dec 27 '22 at 15:34
  • It is never appropriate to edit the resolution into a question's body. – mickmackusa Dec 29 '22 at 21:12
  • Related: [Delete element from triply nested array PHP](https://stackoverflow.com/q/64205049/2943403) and [Delete an array element based on value from nested array](https://stackoverflow.com/q/34930935/2943403) – mickmackusa Dec 29 '22 at 21:17

1 Answers1

1

You can't use array_search() to search nested arrays. Use an ordinary foreach loop.

Note also that you can't use !empty($matchingKey2) to tell if the item was found. If the item is the first element in the array, $matchingKey2 will be 0, which is considered empty. You have to use strict comparison with false.

foreach ($_SESSION["productSummary"] as &$product) {
    $index = array_search(8778, $product['IDs']);
    if ($index !== false) {
        array_splice($product['IDs'], $index, 1);
        break;
    }
}
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • is the '&' sign in the foreach statement intentional or a typo? I haven't seen that used like that before. Fascinating answer though. I think this will solve what I was trying achieve. Thank you – Bo Harris Dec 27 '22 at 15:36
  • It's intentional, to create a reference variable. See https://stackoverflow.com/questions/7733290/how-to-modify-an-arrays-values-by-a-foreach-loop – Barmar Dec 27 '22 at 15:39