1

Here is a code snippet:

$r = [];
$currencies = ['EUR','USD'];
$items = [];
$items[]    = (object)['product_name' => 'product1'];
$items[]    = (object)['product_name' => 'product2'];
$items[]    = (object)['product_name' => 'product3'];

$i = 0;
foreach($currencies as $currency)
{
    foreach($items as $key => $item)
    {
        $items[$key]->field1 = $i++;
        $items[$key]->field2 = $i++;
    }
    print_r($items);
    $r[]    = $items;
}

print_r($r);die('end');

The first two print_r, inside the foreach loop displays the correct arrays with autoincrement values in the fields.

    Array
(
    [0] => stdClass Object
        (
            [product_name] => product1
            [field1] => 0
            [field2] => 1
        )

    [1] => stdClass Object
        (
            [product_name] => product2
            [field1] => 2
            [field2] => 3
        )

    [2] => stdClass Object
        (
            [product_name] => product3
            [field1] => 4
            [field2] => 5
        )

)
Array
(
    [0] => stdClass Object
        (
            [product_name] => product1
            [field1] => 6
            [field2] => 7
        )

    [1] => stdClass Object
        (
            [product_name] => product2
            [field1] => 8
            [field2] => 9
        )

    [2] => stdClass Object
        (
            [product_name] => product3
            [field1] => 10
            [field2] => 11
        )

)

But the last one in the last line displays an array whith two elements where the elements are identical, $r[0] contains the same value as $r[1]

    Array
(
    [0] => Array
        (
            [0] => stdClass Object
                (
                    [product_name] => product1
                    [field1] => 6
                    [field2] => 7
                )

            [1] => stdClass Object
                (
                    [product_name] => product2
                    [field1] => 8
                    [field2] => 9
                )

            [2] => stdClass Object
                (
                    [product_name] => product3
                    [field1] => 10
                    [field2] => 11
                )

        )

    [1] => Array
        (
            [0] => stdClass Object
                (
                    [product_name] => product1
                    [field1] => 6
                    [field2] => 7
                )

            [1] => stdClass Object
                (
                    [product_name] => product2
                    [field1] => 8
                    [field2] => 9
                )

            [2] => stdClass Object
                (
                    [product_name] => product3
                    [field1] => 10
                    [field2] => 11
                )

        )

)

Any guess with this?

5
  • I dont see the problem..? What do you expect? Commented Aug 30, 2018 at 11:13
  • There is no field=0, field=1 etc in the last array. The first element in the last array starts with field=5 which is from the second original array Commented Aug 30, 2018 at 11:17
  • I understand your problem and it is curious. But you may need to explain it more carefully in the question. I only saw what you meant by running the code myself.... Commented Aug 30, 2018 at 11:19
  • The problem is that you are actually always updating the set of 3 values in the $items array. So rather than having copies of the data, you are always referencing the same set of 3 items. Commented Aug 30, 2018 at 11:20
  • 1
    interestingly $r[] = print_r($items,true); works correctly. Commented Aug 30, 2018 at 11:20

1 Answer 1

4

Every $items[$key] is an object, and php works with objects by reference.

This means, that in any of your subarrays $items[$key] points to the same object. And if you change value in one of objects (on second iteration), that reflects all other objects (the ones that were created on first iteration). If you want to use distinct objects - it's better to clone them:

$r = [];
$currencies = ['EUR','USD'];
$items = [];
$items[]    = (object)['product_name' => 'product1'];
$items[]    = (object)['product_name' => 'product2'];
$items[]    = (object)['product_name' => 'product3'];
$i = 0;
foreach($currencies as $currency)
{
    $cloned_items = [];
    foreach($items as $key => $item)
    {
        // `clone` item so to detach it from original item
        $cloned_item = clone $item;   
        $cloned_item->field1 = $i++;
        $cloned_item->field2 = $i++;
        $cloned_items[] = $cloned_item;
    }
    print_r($cloned_items);
    $r[]    = $cloned_items;
}

print_r($r);die('end');

More info about objects and references.

Sign up to request clarification or add additional context in comments.

Comments

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.