1

I have a shopping cart with three items like this:

$cart = [

    1031 => [
        'id'    => '1031',
        'model' => 'tr16',
        'price' => 100,
        'discount_applied' => '',
        'promo_name' => '',
        'promo_id' => ''
    ],
    1032 => [
        'id'    => '1032',
        'model' => 'tr16g',
        'price' => 100,
        'discount_applied' => '',
        'promo_name' => '',
        'promo_id' => ''
    ],
    1034 => [
        'id'    => '1034',
        'model' => 'tr17g',
        'price' => 100,
        'discount_applied' => '',
        'promo_name' => '',
        'promo_id' => ''
    ]
];

I have an array of IDs representing items eligible for a discount like this:

$itemIds = [

    0 => [
        0 => 1031
    ],
    1 => [
        0 => 1032
    ]
];

I loop thru each array and change the price where the ID in $cart matches ID in $itemIds by applying a 20% discount, and also add new elements. That code looks like this:

foreach($cart as &$item) {
    foreach($itemIds as $ids) {
        foreach($ids as $key => $value) { 

            if ($item['id'] == $value)   
            {             
                $item['discount_applied'] = $item['price'] * 0.2;
                $item['price'] = $item['price'] * .80;
                $item['promo_name'] = 'Test promo';
                $item['promo_id'] = 36;
            }     
        }
    }
}

Printing the cart to the screen before and after the loop shows it's working as expected.

However, I encounter a problem when trying to loop through the modified $cart and calculate the sum of individual discounts.

My loop looks like this:

$cart['total_discount'] = 0;
foreach($cart as $item) 
{
    $cart['total_discount'] += $item['discount_applied'];
}
echo 'Total discount:' . $cart['total_discount'];

I expect to see the sum of discounts = 40, but instead = 60. Printing the cart to the screen before and after the loop shows that items 1031 and 1032 have a value of 20 in discount_applied and that item 1034 has no value.

Any help in identifying where I have an error or errors is appreciated.

Here's all the code if you want to copy/paste.

$cart = [

    1031 => [
        'id'    => '1031',
        'model' => 'tr16',
        'price' => 100,
        'discount_applied' => '',
        'promo_name' => '',
        'promo_id' => ''
    ],
    1032 => [
        'id'    => '1032',
        'model' => 'tr16g',
        'price' => 100,
        'discount_applied' => '',
        'promo_name' => '',
        'promo_id' => ''
    ],
    1034 => [
        'id'    => '1034',
        'model' => 'tr17g',
        'price' => 100,
        'discount_applied' => '',
        'promo_name' => '',
        'promo_id' => ''
    ]
];

$itemIds = [

    0 => [
        0 => 1031
    ],
    1 => [
        0 => 1032
    ]
];  

echo '<h2>Cart BEFORE discount</h2>'; echo '<pre>';print_r($cart); echo '</pre>';


foreach($cart as &$item) {
    foreach($itemIds as $ids) {
        foreach($ids as $key => $value) { 

            if ($item['id'] == $value)   
            {             
                $item['discount_applied'] = $item['price'] * 0.2);
                $item['price'] = $item['price'] * .80;
                $item['promo_name'] = 'Test promo';
                $item['promo_id'] = 36;
            }     
        }
    }
}

echo '<h2>Cart AFTER discount</h2>'; echo '<pre>';print_r($cart); echo '</pre>';

$cart['total_discount'] = 0;
foreach($cart as $item) 
{
    echo $item['discount_applied'] . '<br>';
    $cart['total_discount'] += $item['discount_applied'];
}
echo 'Total discount:' . $cart['total_discount'];

1 Answer 1

1

Your use of &$item in the initial loop needs to be used in your final loop also. The loop where you adding up the discount total. You will also need to see if the discount value is a number since, in the code you posted, the 3rd item in the cart will have a blank value for the discount which will throw a non-numeric error when trying to add it to the discount total.

Your final loop modified to work:

$cart['total_discount'] = 0;
foreach($cart as &$item) {
    echo '*' . $item['discount_applied'] . '*<br />';  // just to show what is or isn't there
    $cart['total_discount'] += (is_numeric($item['discount_applied']) ? $item['discount_applied'] : 0);
}
echo 'Total discount:' . $cart['total_discount'];
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you Dave! It works! Beautiful. Love your use of the ternary operator an is_numeric() for data type. Thanks for taking the time to review my code.
There's no need to check if it's numeric, non-numeric strings used as integers will automatically be typecast as integers with value of 0. echo 14 + "foo"; will output 14. (Though PHP 7.2 throws a warning about it.)
Very true @miken32 but in this case there is no value set at all and it throws an error unless you check to see if it's numeric.
If the array element is unset it would complain about running is_numeric() on it as well. I'd go with something like $cart["total_discount"] += (int)$item["discount_applied"] ?? 0; to avoid any warnings or notices.
Right you are so there must have been something there.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.