phantomdentist
phantomdentist

Reputation: 393

Can't understand why my nested php foreach loop is not updating values as expected

Have revised my original code. However am still not managing to actually update my original array. When I echo out echo '<pre>'.print_r( $form['fields'][8]['choices'][0]['text'] ).'</pre>'; I am still getting my original array values. Not much of a programmer so thrashing around in the dark a bit.

$form_id = '6';
$form = GFAPI::get_form( $form_id );

foreach ( $form['fields'] as $key => &$field )
{
    if (isset( $field['id']) && $field['id'] == 47 )
    {
        foreach ( $field['choices'] as $key => &$choice )
        {
            if (isset($choice['value']) && $choice['value'] == 1)
            {
                $choice['text'] = 'test';
                $choice['price'] = '99';

                echo '<pre>'.print_r( $choice['text']).'</pre>';
                echo '<pre>'.print_r( $choice['price']).'</pre>';
            }
        }
    }
}

echo '<pre>'.print_r( $form['fields'][8]['choices'][0]['text'] ).'</pre>';

$result = GFAPI::update_form( $form );
return $result; 

Upvotes: 1

Views: 194

Answers (2)

obe
obe

Reputation: 7808

This line:

foreach ($choices as $key => $choice)

Creates a copy of the array stored in $choices[$key], and $choice refers to that, and not to inside the original $choices array.

If you change it to creating $choice by reference, it should work:

foreach ($choices as $key => &$choice)

But I don't recommend to do that, because there can be subtle side effects in some situations that can be hard to find.

UPDATE:

I tested with this code:

$form = [
    "fields" => [
        8 => [
            "id" => 47,
            "choices" => [
                0 => [
                    "value" => 1,
                    "text" => "original text",
                    "price" => "original price",
                ],
            ],
        ],
    ],
];

foreach ( $form['fields'] as $key => &$field )
{
    if (isset( $field['id']) && $field['id'] == 47 )
    {
        foreach ( $field['choices'] as $key => &$choice )
        {
            if (isset($choice['value']) && $choice['value'] == 1)
            {
                $choice['text'] = 'test';
                $choice['price'] = '99';

                echo "<pre>in-loop text: {$choice["text"]}</pre>";
                echo "<pre>in-loop price: {$choice["price"]}</pre>";
            }
        }
    }
}

echo "<pre>out-of-loop text: {$form['fields'][8]['choices'][0]['text']}</pre>";

The output I got seems to be what I think you expect:

in-loop text: test
in-loop price: 99
out-of-loop text: test

If this is not what you expect then I may have misunderstood the question...

Upvotes: 1

Virender Kumar
Virender Kumar

Reputation: 182

Here you are updating $choices[$key]['text'] value so you can get $choices[$key]['text'].

You need to update value of $choice['text']. Basically you have no need of $key in you foreach loop. This $key can be used if you need to filter data based on key like $key == "some value".

See the updated code

$fields = $form['fields'];
foreach ($fields as $key => $field)
{
    if (isset($fields[$key]['id']) && $fields[$key]['id'] == 47)
    {
        $choices = $fields[$key]['choices'];
        foreach ($choices as $key => $choice)
        {
            if (isset($choice['value']) && $choice['value'] == 1)
            {
                $choice['text'] = 'test';
                $choice['price'] = '99';
                echo '<pre>'.print_r( $choice['text']).'</pre>';
                echo '<pre>'.print_r( $choice['price']).'</pre>';
            }
        }
    }
}

Upvotes: 0

Related Questions